aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/batches
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-11-18 13:28:51 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-11-18 13:28:51 -0800
commit33a5fce6126dc5d3927a71fdc6c35af6f5893fd5 (patch)
tree86dbddbe639d6fb2310e017618c4f5f4f55e9b54 /src/gpu/batches
parent39e7aa48d7ca4c144c457374bf0a0dcc0c5be92d (diff)
Initial implementation of GPU no filter NinePatch
TBR=bsalomon@google.com BUG=skia: Review URL: https://codereview.chromium.org/1454933002
Diffstat (limited to 'src/gpu/batches')
-rw-r--r--src/gpu/batches/GrNinePatch.cpp166
-rw-r--r--src/gpu/batches/GrNinePatch.h24
2 files changed, 190 insertions, 0 deletions
diff --git a/src/gpu/batches/GrNinePatch.cpp b/src/gpu/batches/GrNinePatch.cpp
new file mode 100644
index 0000000000..4c6310ccd4
--- /dev/null
+++ b/src/gpu/batches/GrNinePatch.cpp
@@ -0,0 +1,166 @@
+/*
+ * 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 "GrNinePatch.h"
+
+#include "GrBatchFlushState.h"
+#include "GrDefaultGeoProcFactory.h"
+#include "GrResourceProvider.h"
+#include "GrVertexBatch.h"
+#include "SkBitmap.h"
+#include "SkNinePatchIter.h"
+#include "SkRect.h"
+
+static const GrGeometryProcessor* create_gp(bool readsCoverage) {
+ using namespace GrDefaultGeoProcFactory;
+ Color color(Color::kAttribute_Type);
+ Coverage coverage(readsCoverage ? Coverage::kSolid_Type : Coverage::kNone_Type);
+ LocalCoords localCoords(LocalCoords::kHasExplicit_Type);
+ return GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I());
+}
+
+class GrNonAANinePatchBatch : public GrVertexBatch {
+public:
+ DEFINE_BATCH_CLASS_ID
+
+ static const int kVertsPerRect = 4;
+ static const int kIndicesPerRect = 6;
+ static const int kRectsPerInstance = 9; // We could skip empty rects
+
+ struct Geometry {
+ SkMatrix fViewMatrix;
+ SkIRect fCenter;
+ SkRect fDst;
+ GrColor fColor;
+ };
+
+ GrNonAANinePatchBatch(GrColor color, const SkMatrix& viewMatrix, int imageWidth,
+ int imageHeight, const SkIRect& center, const SkRect &dst)
+ : INHERITED(ClassID()) {
+ Geometry& geo = fGeoData.push_back();
+ geo.fViewMatrix = viewMatrix;
+ geo.fColor = color;
+ geo.fCenter = center;
+ geo.fDst = dst;
+
+ fImageWidth = imageWidth;
+ fImageHeight = imageHeight;
+
+ // setup bounds
+ geo.fViewMatrix.mapRect(&fBounds, geo.fDst);
+ }
+
+ const char* name() const override { return "GrNonAANinePatchBatch"; }
+
+ void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
+ out->setUnknownFourComponents();
+ }
+
+ void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
+ out->setKnownSingleComponent(0xff);
+ }
+
+ SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
+
+private:
+ void onPrepareDraws(Target* target) override {
+ SkAutoTUnref<const GrGeometryProcessor> gp(create_gp(fOpts.readsCoverage()));
+ if (!gp) {
+ SkDebugf("Couldn't create GrGeometryProcessor\n");
+ return;
+ }
+
+ target->initDraw(gp, this->pipeline());
+
+ size_t vertexStride = gp->getVertexStride();
+ int instanceCount = fGeoData.count();
+
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ target->resourceProvider()->refQuadIndexBuffer());
+ InstancedHelper helper;
+ void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
+ indexBuffer, kVertsPerRect,
+ kIndicesPerRect, instanceCount * kRectsPerInstance);
+ if (!vertices || !indexBuffer) {
+ SkDebugf("Could not allocate vertices\n");
+ return;
+ }
+
+ for (int i = 0; i < instanceCount; i++) {
+ intptr_t verts = reinterpret_cast<intptr_t>(vertices) +
+ i * kRectsPerInstance * kVertsPerRect * vertexStride;
+
+ Geometry& geo = fGeoData[i];
+ SkNinePatchIter iter(fImageWidth, fImageHeight, geo.fCenter, geo.fDst);
+
+ SkRect srcR, dstR;
+ while (iter.next(&srcR, &dstR)) {
+ SkPoint* positions = reinterpret_cast<SkPoint*>(verts);
+
+ positions->setRectFan(dstR.fLeft, dstR.fTop,
+ dstR.fRight, dstR.fBottom, vertexStride);
+
+ SkASSERT(!geo.fViewMatrix.hasPerspective());
+ geo.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
+
+ // Setup local coords
+ static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
+ SkPoint* coords = reinterpret_cast<SkPoint*>(verts + kLocalOffset);
+ coords->setRectFan(srcR.fLeft, srcR.fTop, srcR.fRight, srcR.fBottom, vertexStride);
+
+ static const int kColorOffset = sizeof(SkPoint);
+ GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOffset);
+ for (int j = 0; j < 4; ++j) {
+ *vertColor = geo.fColor;
+ vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
+ }
+ verts += kVertsPerRect * vertexStride;
+ }
+ }
+ helper.recordDraw(target);
+ }
+
+ void initBatchTracker(const GrPipelineOptimizations& opt) override {
+ opt.getOverrideColorIfSet(&fGeoData[0].fColor);
+ fOpts = opt;
+ }
+
+ bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
+ GrNonAANinePatchBatch* that = t->cast<GrNonAANinePatchBatch>();
+ if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
+ that->bounds(), caps)) {
+ return false;
+ }
+
+ SkASSERT(this->fImageWidth == that->fImageWidth &&
+ this->fImageHeight == that->fImageHeight);
+
+ // In the event of two batches, one who can tweak, one who cannot, we just fall back to
+ // not tweaking
+ if (fOpts.canTweakAlphaForCoverage() && !that->fOpts.canTweakAlphaForCoverage()) {
+ fOpts = that->fOpts;
+ }
+
+ fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
+ this->joinBounds(that->bounds());
+ return true;
+ }
+
+ GrPipelineOptimizations fOpts;
+ int fImageWidth;
+ int fImageHeight;
+ SkSTArray<1, Geometry, true> fGeoData;
+
+ typedef GrVertexBatch INHERITED;
+};
+
+namespace GrNinePatch {
+GrDrawBatch* CreateNonAA(GrColor color, const SkMatrix& viewMatrix, int imageWidth, int imageHeight,
+ const SkIRect& center, const SkRect& dst) {
+ return new GrNonAANinePatchBatch(color, viewMatrix, imageWidth, imageHeight, center, dst);
+}
+};
diff --git a/src/gpu/batches/GrNinePatch.h b/src/gpu/batches/GrNinePatch.h
new file mode 100644
index 0000000000..0a4ffd6e03
--- /dev/null
+++ b/src/gpu/batches/GrNinePatch.h
@@ -0,0 +1,24 @@
+/*
+ * 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 GrNinePatch_DEFINED
+#define GrNinePatch_DEFINED
+
+#include "GrColor.h"
+
+class GrDrawBatch;
+class SkBitmap;
+class SkMatrix;
+struct SkIRect;
+struct SkRect;
+
+namespace GrNinePatch {
+GrDrawBatch* CreateNonAA(GrColor color, const SkMatrix& viewMatrix, int imageWidth, int imageHeight,
+ const SkIRect& center, const SkRect& dst);
+};
+
+#endif