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
This commit is contained in:
parent
05f85ade78
commit
78a1078f17
179
gm/beziereffects.cpp
Normal file
179
gm/beziereffects.cpp
Normal file
@ -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
|
@ -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
|
||||
|
2
gm/gm.h
2
gm/gm.h
@ -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*);
|
||||
|
@ -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);
|
||||
|
@ -300,8 +300,8 @@
|
||||
],
|
||||
}],
|
||||
[ 'skia_gpu == 1', {
|
||||
'include_dirs': [
|
||||
'../src/gpu', # To pull gl/GrGLUtil.h
|
||||
'dependencies': [
|
||||
'gputest.gyp:skgputest',
|
||||
],
|
||||
}],
|
||||
[ 'skia_os == "nacl"', {
|
||||
|
@ -94,6 +94,9 @@
|
||||
'include_dirs': [
|
||||
'../src/gpu',
|
||||
],
|
||||
'dependencies': [
|
||||
'gputest.gyp:skgputest',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
@ -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',
|
||||
|
38
gyp/gputest.gyp
Normal file
38
gyp/gputest.gyp
Normal file
@ -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:
|
@ -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.
|
||||
|
37
src/gpu/GrTest.cpp
Normal file
37
src/gpu/GrTest.cpp
Normal file
@ -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;
|
||||
}
|
35
src/gpu/GrTest.h
Normal file
35
src/gpu/GrTest.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user