From b091c44c33edbad3466601b29d60bc2eaa4453fa Mon Sep 17 00:00:00 2001 From: jvanverth Date: Fri, 7 Aug 2015 11:49:17 -0700 Subject: [PATCH] Move GrDrawAtlasBatch to separate file Review URL: https://codereview.chromium.org/1274013003 --- gyp/gpu.gypi | 2 + src/gpu/GrDrawAtlasBatch.cpp | 211 +++++++++++++++++++++++++++++++++++ src/gpu/GrDrawAtlasBatch.h | 75 +++++++++++++ src/gpu/GrDrawContext.cpp | 168 +--------------------------- 4 files changed, 292 insertions(+), 164 deletions(-) create mode 100644 src/gpu/GrDrawAtlasBatch.cpp create mode 100644 src/gpu/GrDrawAtlasBatch.h diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index f3f0157b13..4f74f256f3 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -106,6 +106,8 @@ '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.h', '<(skia_src_path)/gpu/GrDefaultPathRenderer.cpp', '<(skia_src_path)/gpu/GrDefaultPathRenderer.h', + '<(skia_src_path)/gpu/GrDrawAtlasBatch.cpp', + '<(skia_src_path)/gpu/GrDrawAtlasBatch.h', '<(skia_src_path)/gpu/GrDrawContext.cpp', '<(skia_src_path)/gpu/GrDrawTarget.cpp', '<(skia_src_path)/gpu/GrDrawTarget.h', diff --git a/src/gpu/GrDrawAtlasBatch.cpp b/src/gpu/GrDrawAtlasBatch.cpp new file mode 100644 index 0000000000..4291542102 --- /dev/null +++ b/src/gpu/GrDrawAtlasBatch.cpp @@ -0,0 +1,211 @@ +/* + * 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 "GrDrawAtlasBatch.h" +#include "GrBatchTest.h" +#include "SkRandom.h" + +void GrDrawAtlasBatch::initBatchTracker(const GrPipelineInfo& init) { + // Handle any color overrides + if (!init.readsColor()) { + fGeoData[0].fColor = GrColor_ILLEGAL; + } + init.getOverrideColorIfSet(&fGeoData[0].fColor); + + // setup batch properties + fColorIgnored = !init.readsColor(); + fColor = fGeoData[0].fColor; + SkASSERT(init.readsLocalCoords()); + fCoverageIgnored = !init.readsCoverage(); +} + +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); +} + +void GrDrawAtlasBatch::generateGeometry(GrBatchTarget* batchTarget) { + int colorOffset = -1, texOffset = -1; + // Setup geometry processor + SkAutoTUnref gp( + set_vertex_attributes(true, this->hasColors(), &colorOffset, + &texOffset, this->color(), this->viewMatrix(), + this->coverageIgnored())); + + batchTarget->initDraw(gp, this->pipeline()); + + int instanceCount = fGeoData.count(); + size_t vertexStride = gp->getVertexStride(); + SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) + + (this->hasColors() ? sizeof(GrColor) : 0)); + + QuadHelper helper; + int numQuads = this->vertexCount()/4; + void* verts = helper.init(batchTarget, vertexStride, numQuads); + if (!verts) { + SkDebugf("Could not allocate vertices\n"); + return; + } + + int vertexOffset = 0; + for (int i = 0; i < instanceCount; i++) { + const Geometry& args = fGeoData[i]; + + 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]; + } + *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; + verts = (void*)((intptr_t)verts + vertexStride); + vertexOffset++; + } + } + helper.issueDraw(batchTarget); +} + +GrDrawAtlasBatch::GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, + const SkPoint* positions, int vertexCount, + const GrColor* colors, const SkPoint* localCoords, + const SkRect& bounds) { + this->initClassID(); + SkASSERT(positions); + SkASSERT(localCoords); + + fViewMatrix = viewMatrix; + Geometry& installedGeo = fGeoData.push_back(geometry); + + installedGeo.fPositions.append(vertexCount, positions); + + if (colors) { + installedGeo.fColors.append(vertexCount, colors); + fHasColors = true; + } else { + fHasColors = false; + } + + installedGeo.fLocalCoords.append(vertexCount, localCoords); + fVertexCount = vertexCount; + + this->setBounds(bounds); +} + +bool GrDrawAtlasBatch::onCombineIfPossible(GrBatch* t) { + if (!this->pipeline()->isEqual(*t->pipeline())) { + return false; + } + + GrDrawAtlasBatch* that = t->cast(); + + // 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->hasColors() && this->color() != that->color()) { + return false; + } + + if (this->color() != that->color()) { + fColor = GrColor_ILLEGAL; + } + fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); + fVertexCount += that->vertexCount(); + + this->joinBounds(that->bounds()); + return true; +} + +#ifdef GR_TEST_UTILS + +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, SkScalar min, SkScalar max, + SkRandom* random, + SkTArray* positions, + SkTArray* texCoords, + SkTArray* colors, bool hasColors) { + for (uint32_t v = 0; v < count; v++) { + positions->push_back(random_point(random, min, max)); + texCoords->push_back(random_point(random, min, max)); + if (hasColors) { + colors->push_back(GrRandomColor(random)); + } + } +} + + +BATCH_TEST_DEFINE(GrDrawAtlasBatch) { + uint32_t spriteCount = random->nextRangeU(1, 100); + + // TODO make 'sensible' indexbuffers + SkTArray positions; + SkTArray texCoords; + SkTArray colors; + + bool hasColors = random->nextBool(); + + uint32_t vertexCount = 4*spriteCount; + + static const SkScalar kMinVertExtent = -100.f; + static const SkScalar kMaxVertExtent = 100.f; + randomize_params(vertexCount, kMinVertExtent, kMaxVertExtent, + random, + &positions, + &texCoords, + &colors, hasColors); + + SkMatrix viewMatrix = GrTest::TestMatrix(random); + SkRect bounds; + SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount); + SkASSERT(result); + + viewMatrix.mapRect(&bounds); + + GrDrawAtlasBatch::Geometry geometry; + geometry.fColor = GrRandomColor(random); + return GrDrawAtlasBatch::Create(geometry, viewMatrix, + positions.begin(), vertexCount, + colors.begin(), + texCoords.begin(), + bounds); +} + +#endif diff --git a/src/gpu/GrDrawAtlasBatch.h b/src/gpu/GrDrawAtlasBatch.h new file mode 100644 index 0000000000..3a47b718cf --- /dev/null +++ b/src/gpu/GrDrawAtlasBatch.h @@ -0,0 +1,75 @@ +/* + * 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 GrDrawAtlasBatch_DEFINED +#define GrDrawAtlasBatch_DEFINED + +#include "GrBatch.h" +#include "GrColor.h" +#include "GrDefaultGeoProcFactory.h" + +class GrDrawAtlasBatch : public GrBatch { +public: + struct Geometry { + GrColor fColor; + SkTDArray fPositions; + SkTDArray fColors; + SkTDArray fLocalCoords; + }; + + static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, + const SkPoint* positions, int vertexCount, + const GrColor* colors, const SkPoint* localCoords, + const SkRect& bounds) { + return SkNEW_ARGS(GrDrawAtlasBatch, (geometry, viewMatrix, positions, + vertexCount, colors, localCoords, bounds)); + } + + const char* name() const override { return "DrawAtlasBatch"; } + + 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; + void generateGeometry(GrBatchTarget* batchTarget) override; + + SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } + +private: + GrDrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, + const SkPoint* positions, int vertexCount, + const GrColor* colors, const SkPoint* localCoords, const SkRect& bounds); + + GrColor color() const { return fColor; } + bool colorIgnored() const { return fColorIgnored; } + const SkMatrix& viewMatrix() const { return fViewMatrix; } + bool hasColors() const { return fHasColors; } + int vertexCount() const { return fVertexCount; } + bool coverageIgnored() const { return fCoverageIgnored; } + + bool onCombineIfPossible(GrBatch* t) override; + SkSTArray<1, Geometry, true> fGeoData; + + SkMatrix fViewMatrix; + GrColor fColor; + int fVertexCount; + bool fColorIgnored; + bool fCoverageIgnored; + bool fHasColors; +}; + +#endif diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 48ff636623..a876ab549b 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -11,6 +11,7 @@ #include "GrBatchTest.h" #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" +#include "GrDrawAtlasBatch.h" #include "GrDrawContext.h" #include "GrOvalRenderer.h" #include "GrPathRenderer.h" @@ -695,167 +696,6 @@ void GrDrawContext::drawVertices(GrRenderTarget* rt, /////////////////////////////////////////////////////////////////////////////// -class DrawAtlasBatch : public GrBatch { -public: - struct Geometry { - GrColor fColor; - SkTDArray fPositions; - SkTDArray fColors; - SkTDArray fLocalCoords; - }; - - static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, - const SkPoint* positions, int vertexCount, - const GrColor* colors, const SkPoint* localCoords, - const SkRect& bounds) { - return SkNEW_ARGS(DrawAtlasBatch, (geometry, viewMatrix, positions, - vertexCount, colors, localCoords, bounds)); - } - - const char* name() const override { return "DrawAtlasBatch"; } - - 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 - fColorIgnored = !init.readsColor(); - fColor = fGeoData[0].fColor; - SkASSERT(init.readsLocalCoords()); - fCoverageIgnored = !init.readsCoverage(); - } - - void generateGeometry(GrBatchTarget* batchTarget) override { - int colorOffset = -1, texOffset = -1; - // Setup geometry processor - SkAutoTUnref gp( - set_vertex_attributes(true, this->hasColors(), &colorOffset, - &texOffset, this->color(), this->viewMatrix(), - this->coverageIgnored())); - - batchTarget->initDraw(gp, this->pipeline()); - - int instanceCount = fGeoData.count(); - size_t vertexStride = gp->getVertexStride(); - SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) - + (this->hasColors() ? sizeof(GrColor) : 0)); - - QuadHelper helper; - int numQuads = this->vertexCount()/4; - void* verts = helper.init(batchTarget, vertexStride, numQuads); - if (!verts) { - SkDebugf("Could not allocate vertices\n"); - return; - } - - int vertexOffset = 0; - for (int i = 0; i < instanceCount; i++) { - const Geometry& args = fGeoData[i]; - - 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]; - } - *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; - verts = (void*)((intptr_t)verts + vertexStride); - vertexOffset++; - } - } - helper.issueDraw(batchTarget); - } - - SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } - -private: - DrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, - const SkPoint* positions, int vertexCount, - const GrColor* colors, const SkPoint* localCoords, const SkRect& bounds) { - this->initClassID(); - SkASSERT(positions); - SkASSERT(localCoords); - - fViewMatrix = viewMatrix; - Geometry& installedGeo = fGeoData.push_back(geometry); - - installedGeo.fPositions.append(vertexCount, positions); - - if (colors) { - installedGeo.fColors.append(vertexCount, colors); - fHasColors = true; - } else { - fHasColors = false; - } - - installedGeo.fLocalCoords.append(vertexCount, localCoords); - fVertexCount = vertexCount; - - this->setBounds(bounds); - } - - GrColor color() const { return fColor; } - bool colorIgnored() const { return fColorIgnored; } - const SkMatrix& viewMatrix() const { return fViewMatrix; } - bool hasColors() const { return fHasColors; } - int vertexCount() const { return fVertexCount; } - bool coverageIgnored() const { return fCoverageIgnored; } - - bool onCombineIfPossible(GrBatch* t) override { - if (!this->pipeline()->isEqual(*t->pipeline())) { - return false; - } - - DrawAtlasBatch* that = t->cast(); - - // 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->hasColors() && this->color() != that->color()) { - return false; - } - - if (this->color() != that->color()) { - fColor = GrColor_ILLEGAL; - } - fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); - fVertexCount += that->vertexCount(); - - this->joinBounds(that->bounds()); - return true; - } - - SkSTArray<1, Geometry, true> fGeoData; - - SkMatrix fViewMatrix; - GrColor fColor; - int fVertexCount; - bool fColorIgnored; - bool fCoverageIgnored; - bool fHasColors; -}; - void GrDrawContext::drawAtlas(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, @@ -925,10 +765,10 @@ void GrDrawContext::drawAtlas(GrRenderTarget* rt, texs = verts + vertCount; vertCols = colorStorage.get(); - DrawAtlasBatch::Geometry geometry; + GrDrawAtlasBatch::Geometry geometry; geometry.fColor = paint.getColor(); - SkAutoTUnref batch(DrawAtlasBatch::Create(geometry, viewMatrix, verts, vertCount, - vertCols, texs, bounds)); + SkAutoTUnref batch(GrDrawAtlasBatch::Create(geometry, viewMatrix, verts, vertCount, + vertCols, texs, bounds)); fDrawTarget->drawBatch(pipelineBuilder, batch); }