diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-21 19:27:48 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-21 19:27:48 +0000 |
commit | 78a1078f17f4f0ae63415298517262a64f706af6 (patch) | |
tree | 6f622a5a976570c22f9806b63f52cccbeacad5a8 | |
parent | 05f85ade7895606badc57e4137c48ee5c8eefab5 (diff) |
Create new target to hold gpu test code, enable direct testing of GrEffects in GM.
R=robertphillips@google.com, jvanverth@google.com, egdaniel@google.com
Author: bsalomon@google.com
Review URL: https://chromiumcodereview.appspot.com/23352003
git-svn-id: http://skia.googlecode.com/svn/trunk@10866 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gm/beziereffects.cpp | 179 | ||||
-rw-r--r-- | gm/bleed.cpp | 4 | ||||
-rw-r--r-- | gm/gm.h | 2 | ||||
-rw-r--r-- | gm/gmmain.cpp | 4 | ||||
-rw-r--r-- | gyp/SampleApp.gyp | 4 | ||||
-rw-r--r-- | gyp/gm.gyp | 3 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | gyp/gputest.gyp | 38 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 4 | ||||
-rw-r--r-- | src/gpu/GrTest.cpp | 37 | ||||
-rw-r--r-- | src/gpu/GrTest.h | 35 |
11 files changed, 303 insertions, 8 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp new file mode 100644 index 0000000000..60474da5cc --- /dev/null +++ b/gm/beziereffects.cpp @@ -0,0 +1,179 @@ + +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This test only works with the GPU backend. + +#include "gm.h" + +#if SK_SUPPORT_GPU && 0 // Can be enabled when cubic effect is checked in. + +#include "GrContext.h" +#include "GrPathUtils.h" +#include "GrTest.h" +#include "SkColorPriv.h" +#include "SkDevice.h" + +// Position & KLM line eq values. These are the vertex attributes for Bezier curves. The last value +// of the Vec4f is ignored. +extern const GrVertexAttrib kAttribs[] = { + {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, + {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} +}; + +static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) { + return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); +} + +namespace skiagm { +/** + * This GM directly exercises effects that draw Bezier curves in the GPU backend. + */ +class BezierEffects : public GM { +public: + BezierEffects() { + this->setBGColor(0xFFFFFFFF); + } + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("bezier_effects"); + } + + virtual SkISize onISize() SK_OVERRIDE { + return make_isize(800, 800); + } + + virtual uint32_t onGetFlags() const SK_OVERRIDE { + // This is a GPU-specific GM. + return kGPUOnly_Flag; + } + + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + SkDevice* device = canvas->getTopDevice(); + GrRenderTarget* rt = device->accessRenderTarget(); + if (NULL == rt) { + return; + } + GrContext* context = rt->getContext(); + if (NULL == context) { + return; + } + + struct Vertex { + SkPoint fPosition; + float fKLM[4]; // The last value is ignored. The effect expects a vec4f. + }; + + static const int kNumCubics = 10; + SkMWCRandom rand; + + int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics))); + int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics) / numCols); + SkScalar w = SkIntToScalar(rt->width()) / numCols; + SkScalar h = SkIntToScalar(rt->height()) / numRows; + int row = 0; + int col = 0; + + for (int i = 0; i < kNumCubics; ++i) { + SkScalar x = SkScalarMul(col, w); + SkScalar y = SkScalarMul(row, h); + SkPoint controlPts[] = { + {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}, + {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}, + {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}, + {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)} + }; + SkPoint chopped[10]; + SkScalar klmEqs[9]; + SkScalar klmSigns[3]; + int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts, + chopped, + klmEqs, + klmSigns, + controlPts); + + SkPaint ctrlPtPaint; + ctrlPtPaint.setColor(rand.nextU() | 0xFF000000); + for (int i = 0; i < 4; ++i) { + canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint); + } + + SkPaint polyPaint; + polyPaint.setColor(0xffA0A0A0); + polyPaint.setStrokeWidth(0); + polyPaint.setStyle(SkPaint::kStroke_Style); + canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint); + + SkPaint choppedPtPaint; + choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000); + + for (int c = 0; c < cnt; ++c) { + SkPoint* pts = chopped + 3 * c; + + for (int i = 0; i < 4; ++i) { + canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint); + } + + SkRect bounds; + bounds.set(pts, 4); + + SkPaint boundsPaint; + boundsPaint.setColor(0xff808080); + boundsPaint.setStrokeWidth(0); + boundsPaint.setStyle(SkPaint::kStroke_Style); + canvas->drawRect(bounds, boundsPaint); + + Vertex verts[4]; + verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop, + bounds.fRight, bounds.fBottom, + sizeof(Vertex)); + for (int v = 0; v < 4; ++v) { + verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]); + verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]); + verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f); + } + + GrTestTarget tt; + context->getTestTarget(&tt); + if (NULL == tt.target()) { + continue; + } + GrDrawState* drawState = tt.target()->drawState(); + drawState->setVertexAttribs<kAttribs>(2); + SkAutoTUnref<GrEffectRef> effect(HairCubicEdgeEffect::Create()); + if (!effect) { + continue; + } + drawState->addCoverageEffect(effect, 1); + drawState->setRenderTarget(rt); + drawState->setColor(0xff000000); + + tt.target()->setVertexSourceToArray(verts, 4); + tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer()); + tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6); + } + ++col; + if (numCols == col) { + col = 0; + ++row; + } + } + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM( return SkNEW(BezierEffects); ) + +} + +#endif diff --git a/gm/bleed.cpp b/gm/bleed.cpp index b61284122b..2d3743a5a2 100644 --- a/gm/bleed.cpp +++ b/gm/bleed.cpp @@ -15,10 +15,6 @@ namespace skiagm { extern GrContext* GetGr(); }; - -void GrContext::setMaxTextureSizeOverride(int maxTextureSizeOverride) { - fMaxTextureSizeOverride = maxTextureSizeOverride; -} #endif // Create a black&white checked texture with a 1-pixel red ring @@ -43,6 +43,8 @@ namespace skiagm { kSkipScaledReplay_Flag = 1 << 6, kSkipGPU_Flag = 1 << 7, kSkipPDFRasterization_Flag = 1 << 8, + + kGPUOnly_Flag = 1 << 9, }; void draw(SkCanvas*); diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 32ad413b9f..ca266e3f95 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -1559,8 +1559,8 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); continue; } - if ((gmFlags & GM::kSkipGPU_Flag) && - kGPU_Backend == config.fBackend) { + if (((gmFlags & GM::kSkipGPU_Flag) && kGPU_Backend == config.fBackend) || + ((gmFlags & GM::kGPUOnly_Flag) && kGPU_Backend != config.fBackend)) { gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig, renderModeDescriptor); errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp index 07516515a6..aa6cbe08d8 100644 --- a/gyp/SampleApp.gyp +++ b/gyp/SampleApp.gyp @@ -300,8 +300,8 @@ ], }], [ 'skia_gpu == 1', { - 'include_dirs': [ - '../src/gpu', # To pull gl/GrGLUtil.h + 'dependencies': [ + 'gputest.gyp:skgputest', ], }], [ 'skia_os == "nacl"', { diff --git a/gyp/gm.gyp b/gyp/gm.gyp index 04efaa6f98..e412efe6cf 100644 --- a/gyp/gm.gyp +++ b/gyp/gm.gyp @@ -94,6 +94,9 @@ 'include_dirs': [ '../src/gpu', ], + 'dependencies': [ + 'gputest.gyp:skgputest', + ], }], ], }, diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 8c183a7ee6..e8950c2da2 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -6,6 +6,7 @@ '../gm/alphagradients.cpp', '../gm/arcofzorro.cpp', '../gm/arithmode.cpp', + '../gm/beziereffects.cpp', '../gm/bicubicfilter.cpp', '../gm/bigmatrix.cpp', '../gm/bigtext.cpp', diff --git a/gyp/gputest.gyp b/gyp/gputest.gyp new file mode 100644 index 0000000000..23d1da3947 --- /dev/null +++ b/gyp/gputest.gyp @@ -0,0 +1,38 @@ +{ + 'targets': [ + { + 'target_name': 'skgputest', + 'product_name': 'skia_skgputest', + 'type': 'static_library', + 'standalone_static_library': 1, + 'dependencies': [ + 'core.gyp:core', + 'gpu.gyp:skgpu', + ], + 'include_dirs': [ + '../include/gpu', + '../include/utils', + '../src/core', + '../src/gpu', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../src/gpu', + ], + }, + 'sources': [ + '<(skia_src_path)/gpu/GrTest.cpp', + '<(skia_src_path)/gpu/GrTest.h', + ], + 'defines': [ + 'GR_IMPLEMENTATION=1', + ], + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index ab3870915b..ae932bd1e4 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -33,6 +33,7 @@ class GrPathRenderer; class GrResourceEntry; class GrResourceCache; class GrStencilBuffer; +class GrTestTarget; class GrTextureParams; class GrVertexBuffer; class GrVertexBufferAllocPool; @@ -825,6 +826,9 @@ public: GrDrawTarget* getTextTarget(); const GrIndexBuffer* getQuadIndexBuffer() const; + // Called by tests that draw directly to the context via GrDrawTarget + void getTestTarget(GrTestTarget*); + /** * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is * called to check the cache for a SB that matches an RT's criteria. diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp new file mode 100644 index 0000000000..934f089f3d --- /dev/null +++ b/src/gpu/GrTest.cpp @@ -0,0 +1,37 @@ + +/* + * 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 "GrTest.h" + +#include "GrGpu.h" + +void GrTestTarget::init(GrContext* ctx, GrDrawTarget* target) { + SkASSERT(!fContext); + + fContext.reset(SkRef(ctx)); + fDrawTarget.reset(SkRef(target)); + + SkNEW_IN_TLAZY(&fASR, GrDrawTarget::AutoStateRestore, (target, GrDrawTarget::kReset_ASRInit)); + SkNEW_IN_TLAZY(&fACR, GrDrawTarget::AutoClipRestore, (target)); + SkNEW_IN_TLAZY(&fAGP, GrDrawTarget::AutoGeometryPush, (target)); +} + +void GrContext::getTestTarget(GrTestTarget* tar) { + this->flush(); + // We could create a proxy GrDrawTarget that passes through to fGpu until ~GrTextTarget() and + // then disconnects. This would help prevent test writers from mixing using the returned + // GrDrawTarget and regular drawing. We could also assert or fail in GrContext drawing methods + // until ~GrTestTarget(). + tar->init(this, fGpu); +} + +/////////////////////////////////////////////////////////////////////////////// + +void GrContext::setMaxTextureSizeOverride(int maxTextureSizeOverride) { + fMaxTextureSizeOverride = maxTextureSizeOverride; +} diff --git a/src/gpu/GrTest.h b/src/gpu/GrTest.h new file mode 100644 index 0000000000..5e61c29a5a --- /dev/null +++ b/src/gpu/GrTest.h @@ -0,0 +1,35 @@ + +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrTest_DEFINED +#define GrTest_DEFINED + +#include "GrContext.h" +#include "GrDrawTarget.h" + +/** Allows a test to temporarily draw to a GrDrawTarget owned by a GrContext. Tests that use this + should be careful not to mix using the GrDrawTarget directly and drawing via SkCanvas or + GrContext. In the future this object may provide some guards to prevent this. */ +class GrTestTarget { +public: + GrTestTarget() {}; + + void init(GrContext*, GrDrawTarget*); + + GrDrawTarget* target() { return fDrawTarget.get(); } + +private: + SkTLazy<GrDrawTarget::AutoStateRestore> fASR; + SkTLazy<GrDrawTarget::AutoClipRestore> fACR; + SkTLazy<GrDrawTarget::AutoGeometryPush> fAGP; + + SkAutoTUnref<GrDrawTarget> fDrawTarget; + SkAutoTUnref<GrContext> fContext; +}; + +#endif |