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

Unified Diff: gm/dcshader.cpp

Issue 816003002: Add device space skshader GM to test kDevice_GrCoordSet (Closed) Base URL: https://skia.googlesource.com/skia.git@kpos
Patch Set: add #if SK_SUPPORT_GPU, make FP a non-local class so it can be a template param in c++03. Created 6 years 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 | « no previous file | gyp/gmslides.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gm/dcshader.cpp
diff --git a/gm/dcshader.cpp b/gm/dcshader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24d548d8d213a8d66b3afc77a365fc8185fff29b
--- /dev/null
+++ b/gm/dcshader.cpp
@@ -0,0 +1,298 @@
+
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#if SK_SUPPORT_GPU
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+#include "gl/GrGLProcessor.h"
+#include "gl/builders/GrGLProgramBuilder.h"
+#include "Resources.h"
+#include "SkShader.h"
+#include "SkStream.h"
+#include "SkTypeface.h"
+
+namespace skiagm {
+
+///////////////////////////////////////////////////////////////////////////////
+
+class DCShader : public SkShader {
+public:
+ DCShader(const SkMatrix& matrix) : fDeviceMatrix(matrix) {}
+
+ Factory getFactory() const SK_OVERRIDE { return NULL; }
+
+ bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& viewM,
+ const SkMatrix* localMatrix, GrColor* color,
+ GrFragmentProcessor** fp) const SK_OVERRIDE;
+private:
+ const SkMatrix fDeviceMatrix;
+};
+
+class DCFP : public GrFragmentProcessor {
+public:
+ DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) {
+ this->addCoordTransform(&fDeviceTransform);
+ this->initClassID<DCFP>();
+ }
+
+ void getGLProcessorKey(const GrGLCaps& caps,
+ GrProcessorKeyBuilder* b) const SK_OVERRIDE {}
+
+ GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE {
+ class DCGLFP : public GrGLFragmentProcessor {
+ void emitCode(GrGLFPBuilder* builder,
+ const GrFragmentProcessor& fp,
+ const char* outputColor,
+ const char* inputColor,
+ const TransformedCoordsArray& coords,
+ const TextureSamplerArray& samplers) {
+ GrGLFPFragmentBuilder* fpb = builder->getFragmentShaderBuilder();
+ fpb->codeAppendf("vec2 c = %s;", fpb->ensureFSCoords2D(coords, 0).c_str());
+ fpb->codeAppend("vec2 r = mod(c, vec2(20.0));");
+ fpb->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5,"
+ "0.5*cos((c.x + c.y) / 15.0) + 0.5,"
+ "(r.x + r.y) / 20.0,"
+ "distance(r, vec2(15.0)) / 20.0 + 0.2);");
+ fpb->codeAppendf("color.rgb *= color.a;"
+ "%s = color * %s;",
+ outputColor, GrGLSLExpr4(inputColor).c_str());
+ }
+ void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
+ };
+ return SkNEW(DCGLFP);
+ }
+
+ const char* name() const SK_OVERRIDE { return "DCFP"; }
+
+ void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
+ inout->mulByUnknownFourComponents();
+ }
+
+private:
+ bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE { return true; }
+
+ GrCoordTransform fDeviceTransform;
+};
+
+bool DCShader::asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& viewM,
+ const SkMatrix* localMatrix, GrColor* color,
+ GrFragmentProcessor** fp) const {
+ *fp = SkNEW_ARGS(DCFP, (fDeviceMatrix));
+ *color = GrColorPackA4(paint.getAlpha());
+ return true;
+}
+
+class DCShaderGM : public GM {
+public:
+ DCShaderGM() {
+ this->setBGColor(0xFFAABBCC);
+ }
+
+ ~DCShaderGM() SK_OVERRIDE {
+ for (int i = 0; i < fPrims.count(); ++i) {
+ SkDELETE(fPrims[i]);
+ }
+ }
+
+protected:
+ uint32_t onGetFlags() const SK_OVERRIDE {
+ return kGPUOnly_Flag;
+ }
+
+ SkString onShortName() SK_OVERRIDE {
+ return SkString("dcshader");
+ }
+
+ SkISize onISize() SK_OVERRIDE { return SkISize::Make(1000, 900); }
+
+ void onOnceBeforeDraw() SK_OVERRIDE {
+ struct Rect : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkRect rect = SkRect::MakeXYWH(0, 0, 50, 50);
+ canvas->drawRect(rect, paint);
+ return rect;
+ }
+ };
+
+ struct Circle : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ static const SkScalar radius = 25;
+ canvas->drawCircle(radius, radius, radius, paint);
+ return SkRect::MakeXYWH(0, 0, 2 * radius, 2 * radius);
+ }
+ };
+
+ struct RRect : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkRRect rrect;
+ rrect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 10, 10);
+ canvas->drawRRect(rrect, paint);
+ return rrect.getBounds();
+ }
+ };
+
+ struct DRRect : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkRRect outerRRect;
+ outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5);
+ SkRRect innerRRect;
+ innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3);
+ canvas->drawDRRect(outerRRect, innerRRect, paint);
+ return outerRRect.getBounds();
+ }
+ };
+ struct Path : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkPath path;
+ path.addCircle(15, 15, 10);
+ path.addOval(SkRect::MakeXYWH(2, 2, 22, 37));
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ canvas->drawPath(path, paint);
+ return path.getBounds();
+ }
+ };
+
+ struct Points : public Prim {
+ Points(SkCanvas::PointMode mode) : fMode(mode) {}
+
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkRandom random;
+ SkPoint points[500];
+ SkRect bounds = SkRect::MakeWH(50, 50);
+ int count = SkToInt(SK_ARRAY_COUNT(points));
+ if (SkCanvas::kPoints_PointMode != fMode) {
+ count = SkTMin(count, 10);
+ }
+ for (int p = 0; p < count; ++p) {
+ points[p].fX = random.nextUScalar1() * bounds.width();
+ points[p].fY = random.nextUScalar1() * bounds.width();
+ }
+ canvas->drawPoints(fMode, count, points, paint);
+ return bounds;
+ }
+ SkCanvas::PointMode fMode;
+ };
+
+ struct Text : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) SK_OVERRIDE {
+ SkPaint paint = origPaint;
+ paint.setTextSize(30.f);
+ this->setFont(&paint);
+ const char* text = this->text();
+ static const SkVector offset = SkVector::Make(10, 10);
+ canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint);
+ SkRect bounds;
+ paint.measureText(text, strlen(text), &bounds);
+ bounds.offset(offset);
+ return bounds;
+ }
+
+ virtual void setFont(SkPaint* paint) {
+ sk_tool_utils::set_portable_typeface(paint);
+ }
+
+ virtual const char* text() const { return "Hello, Skia!"; }
+ };
+
+ struct BmpText : public Text {
+ void setFont(SkPaint* paint) SK_OVERRIDE {
+ if (!fTypeface) {
+ SkString filename = GetResourcePath("/Funkster.ttf");
+ SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
+ if (!stream->isValid()) {
+ SkDebugf("Could not find Funkster.ttf, please set --resourcePath "
+ "correctly.\n");
+ return;
+ }
+ fTypeface.reset(SkTypeface::CreateFromStream(stream));
+ }
+ paint->setTypeface(fTypeface);
+ }
+
+ const char* text() const SK_OVERRIDE { return "Hi, Skia!"; }
+
+ SkAutoTUnref<SkTypeface> fTypeface;
+ };
+ fPrims.push_back(SkNEW(Rect));
+ fPrims.push_back(SkNEW(Circle));
+ fPrims.push_back(SkNEW(RRect));
+ fPrims.push_back(SkNEW(DRRect));
+ fPrims.push_back(SkNEW(Path));
+ fPrims.push_back(SkNEW(Points(SkCanvas::kPoints_PointMode)));
+ fPrims.push_back(SkNEW(Points(SkCanvas::kLines_PointMode)));
+ fPrims.push_back(SkNEW(Points(SkCanvas::kPolygon_PointMode)));
+ fPrims.push_back(SkNEW(Text));
+ fPrims.push_back(SkNEW(BmpText));
+ }
+
+ void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ SkTArray<SkMatrix> devMats;
+ devMats.push_back().reset();
+ devMats.push_back().setRotate(45, 500, 500);
+ devMats.push_back().setRotate(-30, 200, 200);
+ devMats.back().setPerspX(-SkScalarToPersp(SK_Scalar1 / 2000));
+ devMats.back().setPerspY(SkScalarToPersp(SK_Scalar1 / 1000));
+
+
+ SkTArray<SkMatrix> viewMats;
+ viewMats.push_back().setScale(0.75f, 0.75f);
+ viewMats.push_back().setRotate(45, 50, 50);
+ viewMats.back().postScale(0.5f, 1.1f);
+
+ canvas->translate(10, 20);
+ canvas->save();
+ SkScalar tx = 0, maxTy = 0;
+ static const SkScalar kW = 900;
+
+ for (int aa = 0; aa < 2; ++aa) {
+ for (int i = 0; i < fPrims.count(); ++i) {
+ for (int j = 0; j < devMats.count(); ++j) {
+ for (int k = 0; k < viewMats.count(); ++k) {
+ paint.setShader(SkNEW_ARGS(DCShader, (devMats[j])))->unref();
+ paint.setAntiAlias(SkToBool(aa));
+ canvas->save();
+ canvas->concat(viewMats[k]);
+ SkRect bounds = fPrims[i]->draw(canvas, paint);
+ canvas->restore();
+ viewMats[k].mapRect(&bounds);
+ // add margins
+ bounds.fRight += 20;
+ bounds.fBottom += 20;
+ canvas->translate(bounds.fRight, 0);
+ tx += bounds.fRight;
+ maxTy = SkTMax(bounds.fBottom, maxTy);
+ if (tx > kW) {
+ tx = 0;
+ canvas->restore();
+ canvas->translate(0, maxTy);
+ canvas->save();
+ maxTy = 0;
+ }
+ }
+ }
+ }
+ }
+ canvas->restore();
+ }
+
+private:
+ struct Prim {
+ virtual ~Prim() {}
+ virtual SkRect draw(SkCanvas*, const SkPaint&) = 0;
+ };
+
+ SkTArray<Prim*> fPrims;
+
+ typedef GM INHERITED;
+};
+
+DEF_GM( return SkNEW(DCShaderGM); )
+}
+#endif
« no previous file with comments | « no previous file | gyp/gmslides.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698