aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/samplerstress.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-02 13:55:06 +0000
committerGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-02 13:55:06 +0000
commitd9d5385791b9ab47cd482b7d8370336e36867e0e (patch)
treec48b3186f9fee3376153ba213c2ff252c8c9d4c1 /gm/samplerstress.cpp
parent35d50eefbb19d6feb116cd3b0b776e22f8a02eb0 (diff)
Added GM test to stress test the texture unit/sampler allocation
Diffstat (limited to 'gm/samplerstress.cpp')
-rw-r--r--gm/samplerstress.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/gm/samplerstress.cpp b/gm/samplerstress.cpp
new file mode 100644
index 0000000000..64abeeccdd
--- /dev/null
+++ b/gm/samplerstress.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2012 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 "SkCanvas.h"
+#include "SkShader.h"
+#include "SkMaskFilter.h"
+
+namespace skiagm {
+
+
+/**
+ * Simple MaskFilter that creates a screen door stipple pattern
+ */
+class SkStippleMaskFilter : public SkMaskFilter {
+public:
+ SkStippleMaskFilter() : INHERITED() {
+ }
+
+ virtual ~SkStippleMaskFilter() {
+ }
+
+ virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
+ SkIPoint* margin) SK_OVERRIDE {
+
+ if (src.fFormat != SkMask::kA8_Format) {
+ return false;
+ }
+
+ dst->fBounds = src.fBounds;
+ dst->fRowBytes = dst->fBounds.width();
+ dst->fFormat = SkMask::kA8_Format;
+ dst->fImage = NULL;
+
+ if (NULL != src.fImage) {
+ size_t dstSize = dst->computeImageSize();
+ if (0 == dstSize) {
+ return false; // too big to allocate, abort
+ }
+
+ dst->fImage = SkMask::AllocImage(dstSize);
+
+ uint8_t* srcScanLine = src.fImage;
+ uint8_t* scanline = dst->fImage;
+
+ for (int y = 0; y < src.fBounds.height(); ++y) {
+ for (int x = 0; x < src.fBounds.width(); ++x) {
+ SkASSERT(unsigned int(scanline - dst->fImage) < dstSize);
+ scanline[x] = srcScanLine[x] && ((x+y) % 2) ? 0xFF : 0x00;
+ }
+ scanline += dst->fRowBytes;
+ srcScanLine += src.fRowBytes;
+ }
+ }
+
+ return true;
+ }
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW(SkStippleMaskFilter);
+ }
+
+ virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {}
+
+ // getFactory is from SkFlattenable
+ virtual Factory getFactory() SK_OVERRIDE {
+ return CreateProc;
+ }
+
+ // getFormat is from SkMaskFilter
+ virtual SkMask::Format getFormat() SK_OVERRIDE {
+ return SkMask::kA8_Format;
+ }
+protected:
+
+private:
+ typedef SkMaskFilter INHERITED;
+};
+
+/**
+ * Stress test the samplers by rendering a textured glyph with a mask and
+ * an AA clip
+ */
+class SamplerStressGM : public GM {
+public:
+ SamplerStressGM()
+ : fTextureCreated(false)
+ , fShader(NULL)
+ , fMaskFilter(NULL) {
+ }
+
+ virtual ~SamplerStressGM() {
+ }
+
+protected:
+ virtual SkString onShortName() {
+ return SkString("samplerstress");
+ }
+
+ virtual SkISize onISize() {
+ return make_isize(640, 480);
+ }
+
+ /**
+ * Create a red & green stripes on black texture
+ */
+ void createTexture() {
+ if (fTextureCreated) {
+ return;
+ }
+
+ static const int xSize = 16;
+ static const int ySize = 16;
+
+ fTexture.setConfig(SkBitmap::kARGB_8888_Config,
+ xSize,
+ ySize,
+ xSize*sizeof(SkColor));
+
+ fTexture.allocPixels();
+ fTexture.lockPixels();
+ SkPMColor* addr = fTexture.getAddr32(0, 0);
+
+ for (int y = 0; y < ySize; ++y) {
+ for (int x = 0; x < xSize; ++x) {
+ addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK);
+
+ if ((y % 5) == 0) {
+ addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED);
+ }
+ if ((x % 7) == 0) {
+ addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN);
+ }
+ }
+ }
+
+ fTexture.unlockPixels();
+
+ fTextureCreated = true;
+ }
+
+ void createShader() {
+ if (NULL != fShader.get()) {
+ return;
+ }
+
+ createTexture();
+
+ fShader.reset(SkShader::CreateBitmapShader(fTexture,
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode));
+ }
+
+ void createMaskFilter() {
+ if (NULL != fMaskFilter.get()) {
+ return;
+ }
+
+ fMaskFilter.reset(SkNEW(SkStippleMaskFilter));
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+
+ createShader();
+ createMaskFilter();
+
+ canvas->save();
+
+ // draw a letter "M" with a green & red striped texture and a
+ // stipple mask with a round rect soft clip
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(72);
+ paint.setShader(fShader.get());
+ paint.setMaskFilter(fMaskFilter.get());
+
+ SkRect temp;
+ temp.set(SkIntToScalar(115),
+ SkIntToScalar(75),
+ SkIntToScalar(144),
+ SkIntToScalar(110));
+
+ SkPath path;
+ path.addRoundRect(temp, SkIntToScalar(5), SkIntToScalar(5));
+
+ canvas->clipPath(path, SkRegion::kReplace_Op, true); // AA is on
+
+ canvas->drawText("M", 1,
+ SkIntToScalar(100), SkIntToScalar(100),
+ paint);
+
+ canvas->restore();
+
+ // Now draw stroked versions of the "M" and the round rect so we can
+ // see what is going on
+ SkPaint paint2;
+ paint2.setColor(SK_ColorBLACK);
+ paint2.setAntiAlias(true);
+ paint2.setTextSize(72);
+ paint2.setStyle(SkPaint::kStroke_Style);
+ paint2.setStrokeWidth(1);
+ canvas->drawText("M", 1,
+ SkIntToScalar(100), SkIntToScalar(100),
+ paint2);
+
+ paint2.setColor(SK_ColorGRAY);
+
+ canvas->drawPath(path, paint2);
+ }
+
+private:
+ SkBitmap fTexture;
+ bool fTextureCreated;
+ SkAutoTUnref<SkShader> fShader;
+ SkAutoTUnref<SkMaskFilter> fMaskFilter;
+
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new SamplerStressGM; }
+static GMRegistry reg(MyFactory);
+
+}