1b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 2b0ae649b7ebda86ef53bf913798b809d500973edbsalomon/* 3b0ae649b7ebda86ef53bf913798b809d500973edbsalomon * Copyright 2014 Google Inc. 4b0ae649b7ebda86ef53bf913798b809d500973edbsalomon * 5b0ae649b7ebda86ef53bf913798b809d500973edbsalomon * Use of this source code is governed by a BSD-style license that can be 6b0ae649b7ebda86ef53bf913798b809d500973edbsalomon * found in the LICENSE file. 7b0ae649b7ebda86ef53bf913798b809d500973edbsalomon */ 8b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 9b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "gm.h" 10b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#if SK_SUPPORT_GPU 11b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "GrFragmentProcessor.h" 12b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "GrCoordTransform.h" 13b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "gl/GrGLProcessor.h" 14b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "gl/builders/GrGLProgramBuilder.h" 15b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "Resources.h" 1636a364a846dd5cee382069430f376286fe6c3af5mtklein#include "SkReadBuffer.h" 17b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "SkShader.h" 18b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "SkStream.h" 19b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#include "SkTypeface.h" 2036a364a846dd5cee382069430f376286fe6c3af5mtklein#include "SkWriteBuffer.h" 21b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 22b0ae649b7ebda86ef53bf913798b809d500973edbsalomonnamespace skiagm { 23b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 24b0ae649b7ebda86ef53bf913798b809d500973edbsalomon/////////////////////////////////////////////////////////////////////////////// 25b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 26b0ae649b7ebda86ef53bf913798b809d500973edbsalomonclass DCShader : public SkShader { 27b0ae649b7ebda86ef53bf913798b809d500973edbsalomonpublic: 28b0ae649b7ebda86ef53bf913798b809d500973edbsalomon DCShader(const SkMatrix& matrix) : fDeviceMatrix(matrix) {} 29b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 3036a364a846dd5cee382069430f376286fe6c3af5mtklein SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DCShader); 3136a364a846dd5cee382069430f376286fe6c3af5mtklein 3236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buf) const override { 3336a364a846dd5cee382069430f376286fe6c3af5mtklein buf.writeMatrix(fDeviceMatrix); 3436a364a846dd5cee382069430f376286fe6c3af5mtklein } 35b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 36b0ae649b7ebda86ef53bf913798b809d500973edbsalomon bool asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& viewM, 37b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const SkMatrix* localMatrix, GrColor* color, 3836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrFragmentProcessor** fp) const override; 3942dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips 4042dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips#ifndef SK_IGNORE_TO_STRING 4136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void toString(SkString* str) const override { 4242dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips str->appendf("DCShader: ()"); 4342dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips } 4442dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips#endif 4542dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips 46b0ae649b7ebda86ef53bf913798b809d500973edbsalomonprivate: 47b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const SkMatrix fDeviceMatrix; 48b0ae649b7ebda86ef53bf913798b809d500973edbsalomon}; 49b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 5036a364a846dd5cee382069430f376286fe6c3af5mtkleinSkFlattenable* DCShader::CreateProc(SkReadBuffer& buf) { 5136a364a846dd5cee382069430f376286fe6c3af5mtklein SkMatrix matrix; 5236a364a846dd5cee382069430f376286fe6c3af5mtklein buf.readMatrix(&matrix); 5336a364a846dd5cee382069430f376286fe6c3af5mtklein return SkNEW_ARGS(DCShader, (matrix)); 5436a364a846dd5cee382069430f376286fe6c3af5mtklein} 5536a364a846dd5cee382069430f376286fe6c3af5mtklein 56b0ae649b7ebda86ef53bf913798b809d500973edbsalomonclass DCFP : public GrFragmentProcessor { 57b0ae649b7ebda86ef53bf913798b809d500973edbsalomonpublic: 58b0ae649b7ebda86ef53bf913798b809d500973edbsalomon DCFP(const SkMatrix& m) : fDeviceTransform(kDevice_GrCoordSet, m) { 59b0ae649b7ebda86ef53bf913798b809d500973edbsalomon this->addCoordTransform(&fDeviceTransform); 60b0ae649b7ebda86ef53bf913798b809d500973edbsalomon this->initClassID<DCFP>(); 61b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 62b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 63cfc18867d982119d9dc2888bf09f1093012daaddjvanverth void getGLProcessorKey(const GrGLSLCaps& caps, 6436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrProcessorKeyBuilder* b) const override {} 65b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 6636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLFragmentProcessor* createGLInstance() const override { 67b0ae649b7ebda86ef53bf913798b809d500973edbsalomon class DCGLFP : public GrGLFragmentProcessor { 68b0ae649b7ebda86ef53bf913798b809d500973edbsalomon void emitCode(GrGLFPBuilder* builder, 69b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const GrFragmentProcessor& fp, 70b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const char* outputColor, 71b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const char* inputColor, 72b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const TransformedCoordsArray& coords, 73b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const TextureSamplerArray& samplers) { 7429bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fpb = builder->getFragmentShaderBuilder(); 75b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fpb->codeAppendf("vec2 c = %s;", fpb->ensureFSCoords2D(coords, 0).c_str()); 76b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fpb->codeAppend("vec2 r = mod(c, vec2(20.0));"); 77b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fpb->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5," 78b0ae649b7ebda86ef53bf913798b809d500973edbsalomon "0.5*cos((c.x + c.y) / 15.0) + 0.5," 79b0ae649b7ebda86ef53bf913798b809d500973edbsalomon "(r.x + r.y) / 20.0," 80b0ae649b7ebda86ef53bf913798b809d500973edbsalomon "distance(r, vec2(15.0)) / 20.0 + 0.2);"); 81b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fpb->codeAppendf("color.rgb *= color.a;" 82b0ae649b7ebda86ef53bf913798b809d500973edbsalomon "%s = color * %s;", 83b0ae649b7ebda86ef53bf913798b809d500973edbsalomon outputColor, GrGLSLExpr4(inputColor).c_str()); 84b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 8536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void setData(const GrGLProgramDataManager&, const GrProcessor&) override {} 86b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 87b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return SkNEW(DCGLFP); 88b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 89b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 9036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DCFP"; } 91b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 9236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 93b0ae649b7ebda86ef53bf913798b809d500973edbsalomon inout->mulByUnknownFourComponents(); 94b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 95b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 96b0ae649b7ebda86ef53bf913798b809d500973edbsalomonprivate: 9736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 98b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 99b0ae649b7ebda86ef53bf913798b809d500973edbsalomon GrCoordTransform fDeviceTransform; 100b0ae649b7ebda86ef53bf913798b809d500973edbsalomon}; 101b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 102b0ae649b7ebda86ef53bf913798b809d500973edbsalomonbool DCShader::asFragmentProcessor(GrContext*, const SkPaint& paint, const SkMatrix& viewM, 103b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const SkMatrix* localMatrix, GrColor* color, 104b0ae649b7ebda86ef53bf913798b809d500973edbsalomon GrFragmentProcessor** fp) const { 105b0ae649b7ebda86ef53bf913798b809d500973edbsalomon *fp = SkNEW_ARGS(DCFP, (fDeviceMatrix)); 106b0ae649b7ebda86ef53bf913798b809d500973edbsalomon *color = GrColorPackA4(paint.getAlpha()); 107b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return true; 108b0ae649b7ebda86ef53bf913798b809d500973edbsalomon} 109b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 110b0ae649b7ebda86ef53bf913798b809d500973edbsalomonclass DCShaderGM : public GM { 111b0ae649b7ebda86ef53bf913798b809d500973edbsalomonpublic: 112b0ae649b7ebda86ef53bf913798b809d500973edbsalomon DCShaderGM() { 113b0ae649b7ebda86ef53bf913798b809d500973edbsalomon this->setBGColor(0xFFAABBCC); 114b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 115b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 11636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein ~DCShaderGM() override { 117b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int i = 0; i < fPrims.count(); ++i) { 118b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkDELETE(fPrims[i]); 119b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 120b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 121b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 122b0ae649b7ebda86ef53bf913798b809d500973edbsalomonprotected: 123b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 12436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkString onShortName() override { 125b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return SkString("dcshader"); 126b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 127b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 12836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkISize onISize() override { return SkISize::Make(1000, 900); } 129b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 13036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onOnceBeforeDraw() override { 131b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Rect : public Prim { 13236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 133b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRect rect = SkRect::MakeXYWH(0, 0, 50, 50); 134b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawRect(rect, paint); 135b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return rect; 136b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 137b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 138b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 139b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Circle : public Prim { 14036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 141b0ae649b7ebda86ef53bf913798b809d500973edbsalomon static const SkScalar radius = 25; 142b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawCircle(radius, radius, radius, paint); 143b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return SkRect::MakeXYWH(0, 0, 2 * radius, 2 * radius); 144b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 145b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 146b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 147b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct RRect : public Prim { 14836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 149b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRRect rrect; 150b0ae649b7ebda86ef53bf913798b809d500973edbsalomon rrect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 10, 10); 151b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawRRect(rrect, paint); 152b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return rrect.getBounds(); 153b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 154b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 155b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 156b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct DRRect : public Prim { 15736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 158b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRRect outerRRect; 159b0ae649b7ebda86ef53bf913798b809d500973edbsalomon outerRRect.setRectXY(SkRect::MakeXYWH(0, 0, 50, 50), 5, 5); 160b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRRect innerRRect; 161b0ae649b7ebda86ef53bf913798b809d500973edbsalomon innerRRect.setRectXY(SkRect::MakeXYWH(5, 8, 35, 30), 8, 3); 162b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawDRRect(outerRRect, innerRRect, paint); 163b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return outerRRect.getBounds(); 164b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 165b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 166b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Path : public Prim { 16736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 168b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkPath path; 169b0ae649b7ebda86ef53bf913798b809d500973edbsalomon path.addCircle(15, 15, 10); 170b0ae649b7ebda86ef53bf913798b809d500973edbsalomon path.addOval(SkRect::MakeXYWH(2, 2, 22, 37)); 171b0ae649b7ebda86ef53bf913798b809d500973edbsalomon path.setFillType(SkPath::kEvenOdd_FillType); 172b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawPath(path, paint); 173b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return path.getBounds(); 174b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 175b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 176b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 177b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Points : public Prim { 178b0ae649b7ebda86ef53bf913798b809d500973edbsalomon Points(SkCanvas::PointMode mode) : fMode(mode) {} 179b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 18036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& paint) override { 181b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRandom random; 182b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkPoint points[500]; 183b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRect bounds = SkRect::MakeWH(50, 50); 184b0ae649b7ebda86ef53bf913798b809d500973edbsalomon int count = SkToInt(SK_ARRAY_COUNT(points)); 185b0ae649b7ebda86ef53bf913798b809d500973edbsalomon if (SkCanvas::kPoints_PointMode != fMode) { 186b0ae649b7ebda86ef53bf913798b809d500973edbsalomon count = SkTMin(count, 10); 187b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 188b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int p = 0; p < count; ++p) { 189b0ae649b7ebda86ef53bf913798b809d500973edbsalomon points[p].fX = random.nextUScalar1() * bounds.width(); 190b0ae649b7ebda86ef53bf913798b809d500973edbsalomon points[p].fY = random.nextUScalar1() * bounds.width(); 191b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 192b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawPoints(fMode, count, points, paint); 193b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return bounds; 194b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 195b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkCanvas::PointMode fMode; 196b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 197b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 198b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Text : public Prim { 19936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) override { 200b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkPaint paint = origPaint; 201b0ae649b7ebda86ef53bf913798b809d500973edbsalomon paint.setTextSize(30.f); 202b0ae649b7ebda86ef53bf913798b809d500973edbsalomon this->setFont(&paint); 203b0ae649b7ebda86ef53bf913798b809d500973edbsalomon const char* text = this->text(); 204b0ae649b7ebda86ef53bf913798b809d500973edbsalomon static const SkVector offset = SkVector::Make(10, 10); 205b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint); 206b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRect bounds; 207b0ae649b7ebda86ef53bf913798b809d500973edbsalomon paint.measureText(text, strlen(text), &bounds); 208b0ae649b7ebda86ef53bf913798b809d500973edbsalomon bounds.offset(offset); 209b0ae649b7ebda86ef53bf913798b809d500973edbsalomon return bounds; 210b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 211b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 212b0ae649b7ebda86ef53bf913798b809d500973edbsalomon virtual void setFont(SkPaint* paint) { 213b0ae649b7ebda86ef53bf913798b809d500973edbsalomon sk_tool_utils::set_portable_typeface(paint); 214b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 215b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 216b0ae649b7ebda86ef53bf913798b809d500973edbsalomon virtual const char* text() const { return "Hello, Skia!"; } 217b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 218b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 219b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct BmpText : public Text { 22036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void setFont(SkPaint* paint) override { 221b0ae649b7ebda86ef53bf913798b809d500973edbsalomon if (!fTypeface) { 2223ffa126066542590dc7430514a1174e49191b875bungeman fTypeface.reset(GetResourceAsTypeface("/fonts/Funkster.ttf")); 223b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 224b0ae649b7ebda86ef53bf913798b809d500973edbsalomon paint->setTypeface(fTypeface); 225b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 226b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 22736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* text() const override { return "Hi, Skia!"; } 228b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 229b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkAutoTUnref<SkTypeface> fTypeface; 230b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 231b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Rect)); 232b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Circle)); 233b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(RRect)); 234b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(DRRect)); 235b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Path)); 236b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Points(SkCanvas::kPoints_PointMode))); 237b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Points(SkCanvas::kLines_PointMode))); 238b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Points(SkCanvas::kPolygon_PointMode))); 239b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(Text)); 240b0ae649b7ebda86ef53bf913798b809d500973edbsalomon fPrims.push_back(SkNEW(BmpText)); 241b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 242b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 24336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDraw(SkCanvas* canvas) override { 244b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon // This GM exists to test a specific feature of the GPU backend. It does not work with the 245b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon // sw rasterizer, tile modes, etc. 246b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon if (NULL == canvas->getGrContext()) { 247b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon this->drawGpuOnlyMessage(canvas); 248b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon return; 249b62da80cbf6643c1944d3ebf8df233f286bd3fdebsalomon } 250b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkPaint paint; 251b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkTArray<SkMatrix> devMats; 252b0ae649b7ebda86ef53bf913798b809d500973edbsalomon devMats.push_back().reset(); 253b0ae649b7ebda86ef53bf913798b809d500973edbsalomon devMats.push_back().setRotate(45, 500, 500); 254b0ae649b7ebda86ef53bf913798b809d500973edbsalomon devMats.push_back().setRotate(-30, 200, 200); 2553f43f8ab9cd3ba0ea83f5ae0659c21f101dfca7areed devMats.back().setPerspX(-SK_Scalar1 / 2000); 2563f43f8ab9cd3ba0ea83f5ae0659c21f101dfca7areed devMats.back().setPerspY(SK_Scalar1 / 1000); 257b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 258b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 259b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkTArray<SkMatrix> viewMats; 260b0ae649b7ebda86ef53bf913798b809d500973edbsalomon viewMats.push_back().setScale(0.75f, 0.75f); 261b0ae649b7ebda86ef53bf913798b809d500973edbsalomon viewMats.push_back().setRotate(45, 50, 50); 262b0ae649b7ebda86ef53bf913798b809d500973edbsalomon viewMats.back().postScale(0.5f, 1.1f); 263b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 264b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->translate(10, 20); 265b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->save(); 266b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkScalar tx = 0, maxTy = 0; 267b0ae649b7ebda86ef53bf913798b809d500973edbsalomon static const SkScalar kW = 900; 268b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 269b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int aa = 0; aa < 2; ++aa) { 270b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int i = 0; i < fPrims.count(); ++i) { 271b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int j = 0; j < devMats.count(); ++j) { 272b0ae649b7ebda86ef53bf913798b809d500973edbsalomon for (int k = 0; k < viewMats.count(); ++k) { 273b0ae649b7ebda86ef53bf913798b809d500973edbsalomon paint.setShader(SkNEW_ARGS(DCShader, (devMats[j])))->unref(); 274b0ae649b7ebda86ef53bf913798b809d500973edbsalomon paint.setAntiAlias(SkToBool(aa)); 275b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->save(); 276b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->concat(viewMats[k]); 277b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkRect bounds = fPrims[i]->draw(canvas, paint); 278b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->restore(); 279b0ae649b7ebda86ef53bf913798b809d500973edbsalomon viewMats[k].mapRect(&bounds); 280b0ae649b7ebda86ef53bf913798b809d500973edbsalomon // add margins 281b0ae649b7ebda86ef53bf913798b809d500973edbsalomon bounds.fRight += 20; 282b0ae649b7ebda86ef53bf913798b809d500973edbsalomon bounds.fBottom += 20; 283b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->translate(bounds.fRight, 0); 284b0ae649b7ebda86ef53bf913798b809d500973edbsalomon tx += bounds.fRight; 285b0ae649b7ebda86ef53bf913798b809d500973edbsalomon maxTy = SkTMax(bounds.fBottom, maxTy); 286b0ae649b7ebda86ef53bf913798b809d500973edbsalomon if (tx > kW) { 287b0ae649b7ebda86ef53bf913798b809d500973edbsalomon tx = 0; 288b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->restore(); 289b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->translate(0, maxTy); 290b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->save(); 291b0ae649b7ebda86ef53bf913798b809d500973edbsalomon maxTy = 0; 292b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 293b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 294b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 295b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 296b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 297b0ae649b7ebda86ef53bf913798b809d500973edbsalomon canvas->restore(); 298b0ae649b7ebda86ef53bf913798b809d500973edbsalomon } 299b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 300b0ae649b7ebda86ef53bf913798b809d500973edbsalomonprivate: 301b0ae649b7ebda86ef53bf913798b809d500973edbsalomon struct Prim { 302b0ae649b7ebda86ef53bf913798b809d500973edbsalomon virtual ~Prim() {} 303b0ae649b7ebda86ef53bf913798b809d500973edbsalomon virtual SkRect draw(SkCanvas*, const SkPaint&) = 0; 304b0ae649b7ebda86ef53bf913798b809d500973edbsalomon }; 305b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 306b0ae649b7ebda86ef53bf913798b809d500973edbsalomon SkTArray<Prim*> fPrims; 307b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 308b0ae649b7ebda86ef53bf913798b809d500973edbsalomon typedef GM INHERITED; 309b0ae649b7ebda86ef53bf913798b809d500973edbsalomon}; 310b0ae649b7ebda86ef53bf913798b809d500973edbsalomon 311b0ae649b7ebda86ef53bf913798b809d500973edbsalomonDEF_GM( return SkNEW(DCShaderGM); ) 312b0ae649b7ebda86ef53bf913798b809d500973edbsalomon} 313b0ae649b7ebda86ef53bf913798b809d500973edbsalomon#endif 314