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

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: update 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..e2e0bf9ab604373feee426ba632cb959edb68cc5
--- /dev/null
+++ b/gm/dcshader.cpp
@@ -0,0 +1,288 @@
+
+/*
+ * 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"
+#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 {
+ 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) {
+ builder->getFragmentShaderBuilder()->codeAppendf(
+ "vec2 r = mod(%s.xy, vec2(50.0));", coords[0].c_str());
+ builder->getFragmentShaderBuilder()->codeAppendf(
+ "vec4 color = vec4(0.5*sin(%s.x / 25.0) + 0.5,"
+ "0.5*cos((%s.x + %s.y) / 25.0) + 0.5,"
+ "(r.x + r.y) / 25.0,"
+ "distance(r, vec2(25.0)) / 50.0 + 0.2);",
+ coords[0].c_str(), coords[0].c_str(), coords[0].c_str(),
+ coords[0].c_str(), coords[0].c_str());
+ builder->getFragmentShaderBuilder()->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;
+ };
+ *fp = SkNEW_ARGS(DCFP, (fDeviceMatrix));
+ *color = GrColorPackA4(paint.getAlpha());
+ return true;
+ }
+private:
+ const SkMatrix fDeviceMatrix;
+};
+
+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(1200, 900); }
+
+ void onOnceBeforeDraw() SK_OVERRIDE {
+ struct Rect : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ SkRect rect = SkRect::MakeXYWH(0, 0, 100, 100);
+ canvas->drawRect(rect, paint);
+ return rect;
+ }
+ };
+
+ struct Circle : public Prim {
+ SkRect draw(SkCanvas* canvas, const SkPaint& paint) SK_OVERRIDE {
+ static const SkScalar radius = 50;
+ 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, 100, 100), 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, 100, 100), 10, 10);
+ SkRRect innerRRect;
+ innerRRect.setRectXY(SkRect::MakeXYWH(10, 15, 70, 60), 5, 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(30, 30, 20);
+ path.addOval(SkRect::MakeXYWH(5, 5, 45, 75));
+ 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(100, 100);
+ 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(20.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 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");
joshualitt 2014/12/23 02:31:51 nit, but you could line wrap
+ return;
+ }
+ fTypeface.reset(SkTypeface::CreateFromStream(stream));
+ }
+ paint->setTypeface(fTypeface);
+ }
+
+ virtual char* text() const { return "Hello, 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);
+
+ 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);
joshualitt 2014/12/23 02:31:51 I know the shader ignores perspective, but it migh
+
+ canvas->translate(10, 20);
+ canvas->save();
+ SkScalar tx = 0, maxTy = 0;
+ static const SkScalar kW = 1100;
+
+ 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 SkRect draw(SkCanvas*, const SkPaint&) = 0;
+ };
+
+ SkTArray<Prim*> fPrims;
+
+ typedef GM INHERITED;
+};
+
+DEF_GM( return SkNEW(DCShaderGM); )
+}
« 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