diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index d4ce0a42ec..17b67ee901 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -16,11 +16,12 @@ #include "GrContext.h" #include "GrPathUtils.h" #include "GrTest.h" -#include "GrTestBatch.h" #include "SkColorPriv.h" #include "SkDevice.h" #include "SkGeometry.h" +#include "batches/GrTestBatch.h" + #include "effects/GrBezierEffect.h" static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) { diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 665bfe02f6..ba5cc5be25 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -17,12 +17,13 @@ #include "GrDefaultGeoProcFactory.h" #include "GrPathUtils.h" #include "GrTest.h" -#include "GrTestBatch.h" #include "SkColorPriv.h" #include "SkDevice.h" #include "SkGeometry.h" #include "SkTLList.h" +#include "batches/GrTestBatch.h" + #include "effects/GrConvexPolyEffect.h" namespace skiagm { diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index f9d57a795e..60a2dd4c06 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -20,7 +20,7 @@ ' fPositions; - SkTDArray fIndices; - SkTDArray fColors; - SkTDArray fLocalCoords; - }; - - static GrBatch* Create(const Geometry& geometry, 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 SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatrix, positions, - vertexCount, indices, indexCount, colors, - localCoords, bounds)); - } - - const char* name() const override { return "DrawVerticesBatch"; } - - void getInvariantOutputColor(GrInitInvariantOutput* out) const override { - // When this is called on a batch, there is only one geometry bundle - if (this->hasColors()) { - out->setUnknownFourComponents(); - } else { - out->setKnownFourComponents(fGeoData[0].fColor); - } - } - - void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { - out->setKnownSingleComponent(0xff); - } - - void initBatchTracker(const GrPipelineInfo& init) override { - // Handle any color overrides - if (!init.readsColor()) { - fGeoData[0].fColor = GrColor_ILLEGAL; - } - init.getOverrideColorIfSet(&fGeoData[0].fColor); - - // setup batch properties - fBatch.fColorIgnored = !init.readsColor(); - fBatch.fColor = fGeoData[0].fColor; - fBatch.fUsesLocalCoords = init.readsLocalCoords(); - fBatch.fCoverageIgnored = !init.readsCoverage(); - } - - void generateGeometry(GrBatchTarget* batchTarget) override { - int colorOffset = -1, texOffset = -1; - SkAutoTUnref gp( - set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset, - &texOffset, this->color(), this->viewMatrix(), - this->coverageIgnored())); - - batchTarget->initDraw(gp, this->pipeline()); - - size_t vertexStride = gp->getVertexStride(); - - SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0) - + (this->hasColors() ? sizeof(GrColor) : 0)); - - int instanceCount = fGeoData.count(); - - const GrVertexBuffer* vertexBuffer; - int firstVertex; - - void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(), - &vertexBuffer, &firstVertex); - - if (!verts) { - SkDebugf("Could not allocate vertices\n"); - return; - } - - const GrIndexBuffer* indexBuffer = NULL; - int firstIndex = 0; - - uint16_t* indices = NULL; - if (this->hasIndices()) { - indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex); - - if (!indices) { - SkDebugf("Could not allocate indices\n"); - return; - } - } - - int indexOffset = 0; - int vertexOffset = 0; - for (int i = 0; i < instanceCount; i++) { - const Geometry& args = fGeoData[i]; - - // TODO we can actually cache this interleaved and then just memcopy - if (this->hasIndices()) { - for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) { - *(indices + indexOffset) = args.fIndices[j] + vertexOffset; - } - } - - for (int j = 0; j < args.fPositions.count(); ++j) { - *((SkPoint*)verts) = args.fPositions[j]; - if (this->hasColors()) { - *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j]; - } - if (this->hasLocalCoords()) { - *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; - } - verts = (void*)((intptr_t)verts + vertexStride); - vertexOffset++; - } - } - - GrVertices vertices; - if (this->hasIndices()) { - vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, - firstIndex, this->vertexCount(), this->indexCount()); - - } else { - vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); - } - batchTarget->draw(vertices); - } - - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } - -private: - DrawVerticesBatch(const Geometry& geometry, 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) { - this->initClassID(); - SkASSERT(positions); - - fBatch.fViewMatrix = viewMatrix; - Geometry& installedGeo = fGeoData.push_back(geometry); - - installedGeo.fPositions.append(vertexCount, positions); - if (indices) { - installedGeo.fIndices.append(indexCount, indices); - fBatch.fHasIndices = true; - } else { - fBatch.fHasIndices = false; - } - - if (colors) { - installedGeo.fColors.append(vertexCount, colors); - fBatch.fHasColors = true; - } else { - fBatch.fHasColors = false; - } - - if (localCoords) { - installedGeo.fLocalCoords.append(vertexCount, localCoords); - fBatch.fHasLocalCoords = true; - } else { - fBatch.fHasLocalCoords = false; - } - fBatch.fVertexCount = vertexCount; - fBatch.fIndexCount = indexCount; - fBatch.fPrimitiveType = primitiveType; - - this->setBounds(bounds); - } - - GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; } - bool batchablePrimitiveType() const { - return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType || - kLines_GrPrimitiveType == fBatch.fPrimitiveType || - kPoints_GrPrimitiveType == fBatch.fPrimitiveType; - } - GrColor color() const { return fBatch.fColor; } - bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } - bool colorIgnored() const { return fBatch.fColorIgnored; } - const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } - bool hasColors() const { return fBatch.fHasColors; } - bool hasIndices() const { return fBatch.fHasIndices; } - bool hasLocalCoords() const { return fBatch.fHasLocalCoords; } - int vertexCount() const { return fBatch.fVertexCount; } - int indexCount() const { return fBatch.fIndexCount; } - bool coverageIgnored() const { return fBatch.fCoverageIgnored; } - - bool onCombineIfPossible(GrBatch* t) override { - if (!this->pipeline()->isEqual(*t->pipeline())) { - return false; - } - - DrawVerticesBatch* that = t->cast(); - - if (!this->batchablePrimitiveType() || this->primitiveType() != that->primitiveType()) { - return false; - } - - SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); - - // We currently use a uniform viewmatrix for this batch - if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { - return false; - } - - if (this->hasColors() != that->hasColors()) { - return false; - } - - if (this->hasIndices() != that->hasIndices()) { - return false; - } - - if (this->hasLocalCoords() != that->hasLocalCoords()) { - return false; - } - - if (!this->hasColors() && this->color() != that->color()) { - return false; - } - - if (this->color() != that->color()) { - fBatch.fColor = GrColor_ILLEGAL; - } - fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); - fBatch.fVertexCount += that->vertexCount(); - fBatch.fIndexCount += that->indexCount(); - - this->joinBounds(that->bounds()); - return true; - } - - struct BatchTracker { - GrPrimitiveType fPrimitiveType; - SkMatrix fViewMatrix; - GrColor fColor; - bool fUsesLocalCoords; - bool fColorIgnored; - bool fCoverageIgnored; - bool fHasColors; - bool fHasIndices; - bool fHasLocalCoords; - int fVertexCount; - int fIndexCount; - }; - - BatchTracker fBatch; - SkSTArray<1, Geometry, true> fGeoData; -}; - void GrDrawContext::drawVertices(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, @@ -684,12 +407,12 @@ void GrDrawContext::drawVertices(GrRenderTarget* rt, bounds.outset(0.5f, 0.5f); } - DrawVerticesBatch::Geometry geometry; + GrDrawVerticesBatch::Geometry geometry; geometry.fColor = paint.getColor(); - SkAutoTUnref batch(DrawVerticesBatch::Create(geometry, primitiveType, viewMatrix, - positions, vertexCount, indices, - indexCount, colors, texCoords, - bounds)); + SkAutoTUnref batch(GrDrawVerticesBatch::Create(geometry, primitiveType, viewMatrix, + positions, vertexCount, indices, + indexCount, colors, texCoords, + bounds)); fDrawTarget->drawBatch(pipelineBuilder, batch); } @@ -1108,121 +831,3 @@ bool GrDrawContext::prepareToDraw(GrRenderTarget* rt) { void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch) { fDrawTarget->drawBatch(*pipelineBuilder, batch); } - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef GR_TEST_UTILS - -static uint32_t seed_vertices(GrPrimitiveType type) { - switch (type) { - case kTriangles_GrPrimitiveType: - case kTriangleStrip_GrPrimitiveType: - case kTriangleFan_GrPrimitiveType: - return 3; - case kPoints_GrPrimitiveType: - return 1; - case kLines_GrPrimitiveType: - case kLineStrip_GrPrimitiveType: - return 2; - } - SkFAIL("Incomplete switch\n"); - return 0; -} - -static uint32_t primitive_vertices(GrPrimitiveType type) { - switch (type) { - case kTriangles_GrPrimitiveType: - return 3; - case kLines_GrPrimitiveType: - return 2; - case kTriangleStrip_GrPrimitiveType: - case kTriangleFan_GrPrimitiveType: - case kPoints_GrPrimitiveType: - case kLineStrip_GrPrimitiveType: - return 1; - } - SkFAIL("Incomplete switch\n"); - return 0; -} - -static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { - SkPoint p; - p.fX = random->nextRangeScalar(min, max); - p.fY = random->nextRangeScalar(min, max); - return p; -} - -static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max, - SkRandom* random, - SkTArray* positions, - SkTArray* texCoords, bool hasTexCoords, - SkTArray* colors, bool hasColors, - SkTArray* indices, bool hasIndices) { - for (uint32_t v = 0; v < count; v++) { - positions->push_back(random_point(random, min, max)); - if (hasTexCoords) { - texCoords->push_back(random_point(random, min, max)); - } - if (hasColors) { - colors->push_back(GrRandomColor(random)); - } - if (hasIndices) { - SkASSERT(maxVertex <= SK_MaxU16); - indices->push_back(random->nextULessThan((uint16_t)maxVertex)); - } - } -} - -BATCH_TEST_DEFINE(VerticesBatch) { - GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimitiveType + 1)); - uint32_t primitiveCount = random->nextRangeU(1, 100); - - // TODO make 'sensible' indexbuffers - SkTArray positions; - SkTArray texCoords; - SkTArray colors; - SkTArray indices; - - bool hasTexCoords = random->nextBool(); - bool hasIndices = random->nextBool(); - bool hasColors = random->nextBool(); - - uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type); - - static const SkScalar kMinVertExtent = -100.f; - static const SkScalar kMaxVertExtent = 100.f; - randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, - random, - &positions, - &texCoords, hasTexCoords, - &colors, hasColors, - &indices, hasIndices); - - for (uint32_t i = 1; i < primitiveCount; i++) { - randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, - random, - &positions, - &texCoords, hasTexCoords, - &colors, hasColors, - &indices, hasIndices); - } - - SkMatrix viewMatrix = GrTest::TestMatrix(random); - SkRect bounds; - SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount); - SkASSERT(result); - - viewMatrix.mapRect(&bounds); - - DrawVerticesBatch::Geometry geometry; - geometry.fColor = GrRandomColor(random); - return DrawVerticesBatch::Create(geometry, type, viewMatrix, - positions.begin(), vertexCount, - indices.begin(), hasIndices ? vertexCount : 0, - colors.begin(), - texCoords.begin(), - bounds); -} - -#endif - diff --git a/src/gpu/batches/GrDrawVerticesBatch.cpp b/src/gpu/batches/GrDrawVerticesBatch.cpp new file mode 100644 index 0000000000..d302c64949 --- /dev/null +++ b/src/gpu/batches/GrDrawVerticesBatch.cpp @@ -0,0 +1,348 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrDrawVerticesBatch.h" + +#include "GrBatchTarget.h" +#include "GrInvariantOutput.h" +#include "GrDefaultGeoProcFactory.h" + +static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, + bool hasColors, + int* colorOffset, + int* texOffset, + GrColor color, + const SkMatrix& viewMatrix, + bool coverageIgnored) { + using namespace GrDefaultGeoProcFactory; + *texOffset = -1; + *colorOffset = -1; + Color gpColor(color); + if (hasColors) { + gpColor.fType = Color::kAttribute_Type; + } + + Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_Type); + LocalCoords localCoords(hasLocalCoords ? LocalCoords::kHasExplicit_Type : + LocalCoords::kUsePosition_Type); + if (hasLocalCoords && hasColors) { + *colorOffset = sizeof(SkPoint); + *texOffset = sizeof(SkPoint) + sizeof(GrColor); + } else if (hasLocalCoords) { + *texOffset = sizeof(SkPoint); + } else if (hasColors) { + *colorOffset = sizeof(SkPoint); + } + return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewMatrix); +} + +GrDrawVerticesBatch::GrDrawVerticesBatch(const Geometry& geometry, 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) { + this->initClassID(); + SkASSERT(positions); + + fBatch.fViewMatrix = viewMatrix; + Geometry& installedGeo = fGeoData.push_back(geometry); + + installedGeo.fPositions.append(vertexCount, positions); + if (indices) { + installedGeo.fIndices.append(indexCount, indices); + fBatch.fHasIndices = true; + } else { + fBatch.fHasIndices = false; + } + + if (colors) { + installedGeo.fColors.append(vertexCount, colors); + fBatch.fHasColors = true; + } else { + fBatch.fHasColors = false; + } + + if (localCoords) { + installedGeo.fLocalCoords.append(vertexCount, localCoords); + fBatch.fHasLocalCoords = true; + } else { + fBatch.fHasLocalCoords = false; + } + fBatch.fVertexCount = vertexCount; + fBatch.fIndexCount = indexCount; + fBatch.fPrimitiveType = primitiveType; + + this->setBounds(bounds); +} + +void GrDrawVerticesBatch::getInvariantOutputColor(GrInitInvariantOutput* out) const { + // When this is called on a batch, there is only one geometry bundle + if (this->hasColors()) { + out->setUnknownFourComponents(); + } else { + out->setKnownFourComponents(fGeoData[0].fColor); + } +} + +void GrDrawVerticesBatch::getInvariantOutputCoverage(GrInitInvariantOutput* out) const { + out->setKnownSingleComponent(0xff); +} + +void GrDrawVerticesBatch::initBatchTracker(const GrPipelineInfo& init) { + // Handle any color overrides + if (!init.readsColor()) { + fGeoData[0].fColor = GrColor_ILLEGAL; + } + init.getOverrideColorIfSet(&fGeoData[0].fColor); + + // setup batch properties + fBatch.fColorIgnored = !init.readsColor(); + fBatch.fColor = fGeoData[0].fColor; + fBatch.fUsesLocalCoords = init.readsLocalCoords(); + fBatch.fCoverageIgnored = !init.readsCoverage(); +} + +void GrDrawVerticesBatch::generateGeometry(GrBatchTarget* batchTarget) { + int colorOffset = -1, texOffset = -1; + SkAutoTUnref gp( + set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset, + &texOffset, this->color(), this->viewMatrix(), + this->coverageIgnored())); + + batchTarget->initDraw(gp, this->pipeline()); + + size_t vertexStride = gp->getVertexStride(); + + SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0) + + (this->hasColors() ? sizeof(GrColor) : 0)); + + int instanceCount = fGeoData.count(); + + const GrVertexBuffer* vertexBuffer; + int firstVertex; + + void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(), + &vertexBuffer, &firstVertex); + + if (!verts) { + SkDebugf("Could not allocate vertices\n"); + return; + } + + const GrIndexBuffer* indexBuffer = NULL; + int firstIndex = 0; + + uint16_t* indices = NULL; + if (this->hasIndices()) { + indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex); + + if (!indices) { + SkDebugf("Could not allocate indices\n"); + return; + } + } + + int indexOffset = 0; + int vertexOffset = 0; + for (int i = 0; i < instanceCount; i++) { + const Geometry& args = fGeoData[i]; + + // TODO we can actually cache this interleaved and then just memcopy + if (this->hasIndices()) { + for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) { + *(indices + indexOffset) = args.fIndices[j] + vertexOffset; + } + } + + for (int j = 0; j < args.fPositions.count(); ++j) { + *((SkPoint*)verts) = args.fPositions[j]; + if (this->hasColors()) { + *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j]; + } + if (this->hasLocalCoords()) { + *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; + } + verts = (void*)((intptr_t)verts + vertexStride); + vertexOffset++; + } + } + + GrVertices vertices; + if (this->hasIndices()) { + vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, + firstIndex, this->vertexCount(), this->indexCount()); + + } else { + vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); + } + batchTarget->draw(vertices); +} + +bool GrDrawVerticesBatch::onCombineIfPossible(GrBatch* t) { + if (!this->pipeline()->isEqual(*t->pipeline())) { + return false; + } + + GrDrawVerticesBatch* that = t->cast(); + + if (!this->batchablePrimitiveType() || this->primitiveType() != that->primitiveType()) { + return false; + } + + SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); + + // We currently use a uniform viewmatrix for this batch + if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { + return false; + } + + if (this->hasColors() != that->hasColors()) { + return false; + } + + if (this->hasIndices() != that->hasIndices()) { + return false; + } + + if (this->hasLocalCoords() != that->hasLocalCoords()) { + return false; + } + + if (!this->hasColors() && this->color() != that->color()) { + return false; + } + + if (this->color() != that->color()) { + fBatch.fColor = GrColor_ILLEGAL; + } + fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); + fBatch.fVertexCount += that->vertexCount(); + fBatch.fIndexCount += that->indexCount(); + + this->joinBounds(that->bounds()); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef GR_TEST_UTILS + +#include "GrBatchTest.h" + +static uint32_t seed_vertices(GrPrimitiveType type) { + switch (type) { + case kTriangles_GrPrimitiveType: + case kTriangleStrip_GrPrimitiveType: + case kTriangleFan_GrPrimitiveType: + return 3; + case kPoints_GrPrimitiveType: + return 1; + case kLines_GrPrimitiveType: + case kLineStrip_GrPrimitiveType: + return 2; + } + SkFAIL("Incomplete switch\n"); + return 0; +} + +static uint32_t primitive_vertices(GrPrimitiveType type) { + switch (type) { + case kTriangles_GrPrimitiveType: + return 3; + case kLines_GrPrimitiveType: + return 2; + case kTriangleStrip_GrPrimitiveType: + case kTriangleFan_GrPrimitiveType: + case kPoints_GrPrimitiveType: + case kLineStrip_GrPrimitiveType: + return 1; + } + SkFAIL("Incomplete switch\n"); + return 0; +} + +static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { + SkPoint p; + p.fX = random->nextRangeScalar(min, max); + p.fY = random->nextRangeScalar(min, max); + return p; +} + +static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max, + SkRandom* random, + SkTArray* positions, + SkTArray* texCoords, bool hasTexCoords, + SkTArray* colors, bool hasColors, + SkTArray* indices, bool hasIndices) { + for (uint32_t v = 0; v < count; v++) { + positions->push_back(random_point(random, min, max)); + if (hasTexCoords) { + texCoords->push_back(random_point(random, min, max)); + } + if (hasColors) { + colors->push_back(GrRandomColor(random)); + } + if (hasIndices) { + SkASSERT(maxVertex <= SK_MaxU16); + indices->push_back(random->nextULessThan((uint16_t)maxVertex)); + } + } +} + +BATCH_TEST_DEFINE(VerticesBatch) { + GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimitiveType + 1)); + uint32_t primitiveCount = random->nextRangeU(1, 100); + + // TODO make 'sensible' indexbuffers + SkTArray positions; + SkTArray texCoords; + SkTArray colors; + SkTArray indices; + + bool hasTexCoords = random->nextBool(); + bool hasIndices = random->nextBool(); + bool hasColors = random->nextBool(); + + uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type); + + static const SkScalar kMinVertExtent = -100.f; + static const SkScalar kMaxVertExtent = 100.f; + randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, + random, + &positions, + &texCoords, hasTexCoords, + &colors, hasColors, + &indices, hasIndices); + + for (uint32_t i = 1; i < primitiveCount; i++) { + randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, + random, + &positions, + &texCoords, hasTexCoords, + &colors, hasColors, + &indices, hasIndices); + } + + SkMatrix viewMatrix = GrTest::TestMatrix(random); + SkRect bounds; + SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount); + SkASSERT(result); + + viewMatrix.mapRect(&bounds); + + GrDrawVerticesBatch::Geometry geometry; + geometry.fColor = GrRandomColor(random); + return GrDrawVerticesBatch::Create(geometry, type, viewMatrix, + positions.begin(), vertexCount, + indices.begin(), hasIndices ? vertexCount : 0, + colors.begin(), + texCoords.begin(), + bounds); +} + +#endif diff --git a/src/gpu/batches/GrDrawVerticesBatch.h b/src/gpu/batches/GrDrawVerticesBatch.h new file mode 100644 index 0000000000..86ce241116 --- /dev/null +++ b/src/gpu/batches/GrDrawVerticesBatch.h @@ -0,0 +1,99 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrDrawVerticesBatch_DEFINED +#define GrDrawVerticesBatch_DEFINED + +#include "GrBatch.h" +#include "GrColor.h" +#include "GrTypes.h" +#include "SkMatrix.h" +#include "SkRect.h" +#include "SkTDArray.h" + +class GrBatch; +class GrBatchTarget; +struct GrInitInvariantOutput; + +class GrDrawVerticesBatch : public GrBatch { +public: + struct Geometry { + GrColor fColor; + SkTDArray fPositions; + SkTDArray fIndices; + SkTDArray fColors; + SkTDArray fLocalCoords; + }; + + static GrBatch* Create(const Geometry& geometry, 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 SkNEW_ARGS(GrDrawVerticesBatch, (geometry, primitiveType, viewMatrix, positions, + vertexCount, indices, indexCount, colors, + localCoords, bounds)); + } + + const char* name() const override { return "DrawVerticesBatch"; } + + void getInvariantOutputColor(GrInitInvariantOutput* out) const override; + + void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override; + + void initBatchTracker(const GrPipelineInfo& init) override; + + void generateGeometry(GrBatchTarget* batchTarget) override; + + SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } + +private: + GrDrawVerticesBatch(const Geometry& geometry, 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); + + GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; } + bool batchablePrimitiveType() const { + return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType || + kLines_GrPrimitiveType == fBatch.fPrimitiveType || + kPoints_GrPrimitiveType == fBatch.fPrimitiveType; + } + GrColor color() const { return fBatch.fColor; } + bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } + bool colorIgnored() const { return fBatch.fColorIgnored; } + const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } + bool hasColors() const { return fBatch.fHasColors; } + bool hasIndices() const { return fBatch.fHasIndices; } + bool hasLocalCoords() const { return fBatch.fHasLocalCoords; } + int vertexCount() const { return fBatch.fVertexCount; } + int indexCount() const { return fBatch.fIndexCount; } + bool coverageIgnored() const { return fBatch.fCoverageIgnored; } + + bool onCombineIfPossible(GrBatch* t) override; + + struct BatchTracker { + GrPrimitiveType fPrimitiveType; + SkMatrix fViewMatrix; + GrColor fColor; + bool fUsesLocalCoords; + bool fColorIgnored; + bool fCoverageIgnored; + bool fHasColors; + bool fHasIndices; + bool fHasLocalCoords; + int fVertexCount; + int fIndexCount; + }; + + BatchTracker fBatch; + SkSTArray<1, Geometry, true> fGeoData; +}; + +#endif diff --git a/src/gpu/GrTestBatch.h b/src/gpu/batches/GrTestBatch.h similarity index 100% rename from src/gpu/GrTestBatch.h rename to src/gpu/batches/GrTestBatch.h