drawatlas.cpp revision 9ce9d6772df650ceb0511f275e1a83dffa78ff72
171c3c760a83123ee0b3127b8c65c6394ce541c50reed/*
271c3c760a83123ee0b3127b8c65c6394ce541c50reed * Copyright 2015 Google Inc.
371c3c760a83123ee0b3127b8c65c6394ce541c50reed *
471c3c760a83123ee0b3127b8c65c6394ce541c50reed * Use of this source code is governed by a BSD-style license that can be
571c3c760a83123ee0b3127b8c65c6394ce541c50reed * found in the LICENSE file.
671c3c760a83123ee0b3127b8c65c6394ce541c50reed */
771c3c760a83123ee0b3127b8c65c6394ce541c50reed
871c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "gm.h"
971c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkCanvas.h"
1071c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkRSXform.h"
1171c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkSurface.h"
1271c3c760a83123ee0b3127b8c65c6394ce541c50reed
1371c3c760a83123ee0b3127b8c65c6394ce541c50reedclass DrawAtlasGM : public skiagm::GM {
149ce9d6772df650ceb0511f275e1a83dffa78ff72reed    static sk_sp<SkImage> MakeAtlas(SkCanvas* caller, const SkRect& target) {
1571c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
1671c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
1796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == surface) {
1871c3c760a83123ee0b3127b8c65c6394ce541c50reed            surface.reset(SkSurface::NewRaster(info));
1971c3c760a83123ee0b3127b8c65c6394ce541c50reed        }
2071c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkCanvas* canvas = surface->getCanvas();
2171c3c760a83123ee0b3127b8c65c6394ce541c50reed        // draw red everywhere, but we don't expect to see it in the draw, testing the notion
2271c3c760a83123ee0b3127b8c65c6394ce541c50reed        // that drawAtlas draws a subset-region of the atlas.
2371c3c760a83123ee0b3127b8c65c6394ce541c50reed        canvas->clear(SK_ColorRED);
2471c3c760a83123ee0b3127b8c65c6394ce541c50reed
2571c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkPaint paint;
2671c3c760a83123ee0b3127b8c65c6394ce541c50reed        paint.setXfermodeMode(SkXfermode::kClear_Mode);
2771c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkRect r(target);
2871c3c760a83123ee0b3127b8c65c6394ce541c50reed        r.inset(-1, -1);
2971c3c760a83123ee0b3127b8c65c6394ce541c50reed        // zero out a place (with a 1-pixel border) to land our drawing.
3071c3c760a83123ee0b3127b8c65c6394ce541c50reed        canvas->drawRect(r, paint);
3196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        paint.setXfermode(nullptr);
3271c3c760a83123ee0b3127b8c65c6394ce541c50reed        paint.setColor(SK_ColorBLUE);
3371c3c760a83123ee0b3127b8c65c6394ce541c50reed        paint.setAntiAlias(true);
3471c3c760a83123ee0b3127b8c65c6394ce541c50reed        canvas->drawOval(target, paint);
359ce9d6772df650ceb0511f275e1a83dffa78ff72reed        return surface->makeImageSnapshot();
3671c3c760a83123ee0b3127b8c65c6394ce541c50reed    }
3771c3c760a83123ee0b3127b8c65c6394ce541c50reed
389ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage> fAtlas;
3971c3c760a83123ee0b3127b8c65c6394ce541c50reed
4071c3c760a83123ee0b3127b8c65c6394ce541c50reedpublic:
4171c3c760a83123ee0b3127b8c65c6394ce541c50reed    DrawAtlasGM() {}
4271c3c760a83123ee0b3127b8c65c6394ce541c50reed
4371c3c760a83123ee0b3127b8c65c6394ce541c50reedprotected:
4471c3c760a83123ee0b3127b8c65c6394ce541c50reed
4571c3c760a83123ee0b3127b8c65c6394ce541c50reed    SkString onShortName() override {
4671c3c760a83123ee0b3127b8c65c6394ce541c50reed        return SkString("draw-atlas");
4771c3c760a83123ee0b3127b8c65c6394ce541c50reed    }
4871c3c760a83123ee0b3127b8c65c6394ce541c50reed
4971c3c760a83123ee0b3127b8c65c6394ce541c50reed    SkISize onISize() override {
5071c3c760a83123ee0b3127b8c65c6394ce541c50reed        return SkISize::Make(640, 480);
5171c3c760a83123ee0b3127b8c65c6394ce541c50reed    }
5271c3c760a83123ee0b3127b8c65c6394ce541c50reed
5371c3c760a83123ee0b3127b8c65c6394ce541c50reed    void onDraw(SkCanvas* canvas) override {
5471c3c760a83123ee0b3127b8c65c6394ce541c50reed        const SkRect target = { 50, 50, 80, 90 };
5596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == fAtlas) {
569ce9d6772df650ceb0511f275e1a83dffa78ff72reed            fAtlas = MakeAtlas(canvas, target);
5771c3c760a83123ee0b3127b8c65c6394ce541c50reed        }
5871c3c760a83123ee0b3127b8c65c6394ce541c50reed
5971c3c760a83123ee0b3127b8c65c6394ce541c50reed        const struct {
6071c3c760a83123ee0b3127b8c65c6394ce541c50reed            SkScalar fScale;
6171c3c760a83123ee0b3127b8c65c6394ce541c50reed            SkScalar fDegrees;
6271c3c760a83123ee0b3127b8c65c6394ce541c50reed            SkScalar fTx;
6371c3c760a83123ee0b3127b8c65c6394ce541c50reed            SkScalar fTy;
6471c3c760a83123ee0b3127b8c65c6394ce541c50reed
6571c3c760a83123ee0b3127b8c65c6394ce541c50reed            void apply(SkRSXform* xform) const {
6671c3c760a83123ee0b3127b8c65c6394ce541c50reed                const SkScalar rad = SkDegreesToRadians(fDegrees);
6771c3c760a83123ee0b3127b8c65c6394ce541c50reed                xform->fSCos = fScale * SkScalarCos(rad);
6871c3c760a83123ee0b3127b8c65c6394ce541c50reed                xform->fSSin = fScale * SkScalarSin(rad);
6971c3c760a83123ee0b3127b8c65c6394ce541c50reed                xform->fTx   = fTx;
7071c3c760a83123ee0b3127b8c65c6394ce541c50reed                xform->fTy   = fTy;
7171c3c760a83123ee0b3127b8c65c6394ce541c50reed            }
7271c3c760a83123ee0b3127b8c65c6394ce541c50reed        } rec[] = {
7371c3c760a83123ee0b3127b8c65c6394ce541c50reed            { 1, 0, 10, 10 },       // just translate
7471c3c760a83123ee0b3127b8c65c6394ce541c50reed            { 2, 0, 110, 10 },      // scale + translate
7571c3c760a83123ee0b3127b8c65c6394ce541c50reed            { 1, 30, 210, 10 },     // rotate + translate
7671c3c760a83123ee0b3127b8c65c6394ce541c50reed            { 2, -30, 310, 30 },    // scale + rotate + translate
7771c3c760a83123ee0b3127b8c65c6394ce541c50reed        };
7871c3c760a83123ee0b3127b8c65c6394ce541c50reed
7971c3c760a83123ee0b3127b8c65c6394ce541c50reed        const int N = SK_ARRAY_COUNT(rec);
8071c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkRSXform xform[N];
8171c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkRect tex[N];
8271c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkColor colors[N];
8371c3c760a83123ee0b3127b8c65c6394ce541c50reed
8471c3c760a83123ee0b3127b8c65c6394ce541c50reed        for (int i = 0; i < N; ++i) {
8571c3c760a83123ee0b3127b8c65c6394ce541c50reed            rec[i].apply(&xform[i]);
8671c3c760a83123ee0b3127b8c65c6394ce541c50reed            tex[i] = target;
8771c3c760a83123ee0b3127b8c65c6394ce541c50reed            colors[i] = 0x80FF0000 + (i * 40 * 256);
8871c3c760a83123ee0b3127b8c65c6394ce541c50reed        }
8971c3c760a83123ee0b3127b8c65c6394ce541c50reed
9071c3c760a83123ee0b3127b8c65c6394ce541c50reed        SkPaint paint;
9171c3c760a83123ee0b3127b8c65c6394ce541c50reed        paint.setFilterQuality(kLow_SkFilterQuality);
9271c3c760a83123ee0b3127b8c65c6394ce541c50reed        paint.setAntiAlias(true);
9371c3c760a83123ee0b3127b8c65c6394ce541c50reed
949ce9d6772df650ceb0511f275e1a83dffa78ff72reed        canvas->drawAtlas(fAtlas.get(), xform, tex, N, nullptr, &paint);
9571c3c760a83123ee0b3127b8c65c6394ce541c50reed        canvas->translate(0, 100);
969ce9d6772df650ceb0511f275e1a83dffa78ff72reed        canvas->drawAtlas(fAtlas.get(), xform, tex, colors, N, SkXfermode::kSrcIn_Mode, nullptr, &paint);
9771c3c760a83123ee0b3127b8c65c6394ce541c50reed    }
9871c3c760a83123ee0b3127b8c65c6394ce541c50reed
9971c3c760a83123ee0b3127b8c65c6394ce541c50reedprivate:
10071c3c760a83123ee0b3127b8c65c6394ce541c50reed    typedef GM INHERITED;
10171c3c760a83123ee0b3127b8c65c6394ce541c50reed};
10271c3c760a83123ee0b3127b8c65c6394ce541c50reedDEF_GM( return new DrawAtlasGM; )
10371c3c760a83123ee0b3127b8c65c6394ce541c50reed
104