| Index: gm/mixedxfermodes.cpp
|
| ===================================================================
|
| --- gm/mixedxfermodes.cpp (revision 0)
|
| +++ gm/mixedxfermodes.cpp (revision 0)
|
| @@ -0,0 +1,111 @@
|
| +
|
| +/*
|
| + * Copyright 2013 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 "SkBitmap.h"
|
| +#include "SkRandom.h"
|
| +#include "SkShader.h"
|
| +#include "SkXfermode.h"
|
| +
|
| +namespace skiagm {
|
| +
|
| +/**
|
| + * Renders overlapping circles with random SkXfermode::Modes against a checkerboard.
|
| + */
|
| +class MixedXfermodesGM : public GM {
|
| +public:
|
| + MixedXfermodesGM() {
|
| + static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF };
|
| + SkBitmap bitmap;
|
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 2 * sizeof(uint32_t));
|
| + bitmap.allocPixels();
|
| + bitmap.lockPixels();
|
| + memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData));
|
| + bitmap.unlockPixels();
|
| + fBG.reset(SkShader::CreateBitmapShader(bitmap,
|
| + SkShader::kRepeat_TileMode,
|
| + SkShader::kRepeat_TileMode));
|
| + SkASSERT(NULL != fBG);
|
| + SkMatrix lm;
|
| + lm.setScale(SkIntToScalar(20), SkIntToScalar(20));
|
| + fBG->setLocalMatrix(lm);
|
| + }
|
| +
|
| +protected:
|
| + virtual SkString onShortName() {
|
| + return SkString("mixed_xfermodes");
|
| + }
|
| +
|
| + virtual SkISize onISize() {
|
| + return make_isize(790, 640);
|
| + }
|
| +
|
| + virtual void onDraw(SkCanvas* canvas) {
|
| + // FIXME: Currently necessary for GPU to be able to make dst-copy in SampleApp because
|
| + // main layer is not a texture.
|
| + SkPaint layerPaint;
|
| + layerPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
| + canvas->saveLayer(NULL, &layerPaint);
|
| +
|
| + SkPaint bgPaint;
|
| + bgPaint.setShader(fBG.get());
|
| + canvas->drawPaint(bgPaint);
|
| + SkISize size = canvas->getDeviceSize();
|
| + SkScalar areaSqrt = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeight)));
|
| + SkScalar minR = areaSqrt / 10;
|
| + SkScalar maxR = areaSqrt / 4;
|
| + SkMWCRandom random;
|
| + for (int i = 0; i < kNumCircles; ++i) {
|
| + SkScalar cx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth));
|
| + SkScalar cy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight));
|
| + SkScalar r = random.nextRangeScalar(minR, maxR);
|
| + SkColor color = random.nextU();
|
| +
|
| + SkXfermode::Mode mode =
|
| + static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::kLastMode + 1));
|
| + // FIXME: Currently testing kDarken on GPU.
|
| + mode = SkXfermode::kDarken_Mode;
|
| +
|
| + SkPaint p;
|
| + p.setAntiAlias(true);
|
| + p.setColor(color);
|
| + p.setXfermodeMode(mode);
|
| + canvas->drawCircle(cx, cy, r, p);
|
| + }
|
| +
|
| + // FIXME: Remove text draw once this GM is finished.
|
| + SkPaint txtPaint;
|
| + txtPaint.setTextSize(areaSqrt / 20);
|
| + txtPaint.setAntiAlias(true);
|
| + static const char kTxt[] = "Work in progres... Do not baseline.";
|
| + canvas->drawText(kTxt, strlen(kTxt),
|
| + areaSqrt/50,
|
| + SkIntToScalar(size.fHeight / 2),
|
| + txtPaint);
|
| +
|
| + canvas->restore();
|
| + }
|
| +
|
| + // https://code.google.com/p/skia/issues/detail?id=1199&thanks=1199&ts=1364839297
|
| + virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPipe_Flag; }
|
| +
|
| +private:
|
| + enum {
|
| + kMinR = 10,
|
| + kMaxR = 50,
|
| + kNumCircles = 50,
|
| + };
|
| + SkAutoTUnref<SkShader> fBG;
|
| + typedef GM INHERITED;
|
| +};
|
| +
|
| +//////////////////////////////////////////////////////////////////////////////
|
| +
|
| +static GM* MyFactory(void*) { return new MixedXfermodesGM; }
|
| +static GMRegistry reg(MyFactory);
|
| +
|
| +}
|
|
|