Make GMs aware of what tool they're being run in.
Add a saveLayer set of draws to convex_poly_clip and fix GPU bug where polygon clips don't account for the translation between clip and device space. BUG=skia:2051 R=robertphillips@google.com, reed@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/148283017 git-svn-id: http://skia.googlecode.com/svn/trunk@13371 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
5bc7339aab
commit
b21fac156d
@ -55,6 +55,7 @@ public:
|
||||
|
||||
virtual SkBenchmark* operator()() const SK_OVERRIDE {
|
||||
skiagm::GM* gm = fGMFactory(NULL);
|
||||
gm->setMode(skiagm::GM::kBench_Mode);
|
||||
return SkNEW_ARGS(SkGMBench, (gm));
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,12 @@ protected:
|
||||
}
|
||||
|
||||
virtual SkISize onISize() SK_OVERRIDE {
|
||||
return make_isize(435, 540);
|
||||
// When benchmarking the saveLayer set of draws is skipped.
|
||||
int w = 435;
|
||||
if (kBench_Mode != this->getMode()) {
|
||||
w *= 2;
|
||||
}
|
||||
return make_isize(w, 540);
|
||||
}
|
||||
|
||||
virtual void onOnceBeforeDraw() SK_OVERRIDE {
|
||||
@ -140,47 +145,70 @@ protected:
|
||||
SkIntToScalar(size.fHeight));
|
||||
canvas->drawBitmapRectToRect(fBmp, NULL, dstRect, &bgPaint);
|
||||
|
||||
for (SkTLList<Clip>::Iter iter(fClips, SkTLList<Clip>::Iter::kHead_IterStart);
|
||||
NULL != iter.get();
|
||||
iter.next()) {
|
||||
const Clip* clip = iter.get();
|
||||
SkScalar x = 0;
|
||||
for (int aa = 0; aa < 2; ++aa) {
|
||||
canvas->save();
|
||||
canvas->translate(x, y);
|
||||
clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
|
||||
canvas->drawBitmap(fBmp, 0, 0);
|
||||
canvas->restore();
|
||||
x += fBmp.width() + kMargin;
|
||||
static const char kTxt[] = "Clip Me!";
|
||||
SkPaint txtPaint;
|
||||
txtPaint.setTextSize(23.f);
|
||||
txtPaint.setAntiAlias(true);
|
||||
txtPaint.setColor(SK_ColorDKGRAY);
|
||||
SkScalar textW = txtPaint.measureText(kTxt, SK_ARRAY_COUNT(kTxt)-1);
|
||||
|
||||
SkScalar startX = 0;
|
||||
int testLayers = kBench_Mode != this->getMode();
|
||||
for (int doLayer = 0; doLayer <= testLayers; ++doLayer) {
|
||||
for (SkTLList<Clip>::Iter iter(fClips, SkTLList<Clip>::Iter::kHead_IterStart);
|
||||
NULL != iter.get();
|
||||
iter.next()) {
|
||||
const Clip* clip = iter.get();
|
||||
SkScalar x = startX;
|
||||
for (int aa = 0; aa < 2; ++aa) {
|
||||
if (doLayer) {
|
||||
SkRect bounds;
|
||||
clip->getBounds(&bounds);
|
||||
bounds.outset(2, 2);
|
||||
bounds.offset(x, y);
|
||||
canvas->saveLayer(&bounds, NULL);
|
||||
} else {
|
||||
canvas->save();
|
||||
}
|
||||
canvas->translate(x, y);
|
||||
clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
|
||||
canvas->drawBitmap(fBmp, 0, 0);
|
||||
canvas->restore();
|
||||
x += fBmp.width() + kMargin;
|
||||
}
|
||||
for (int aa = 0; aa < 2; ++aa) {
|
||||
|
||||
SkPaint clipOutlinePaint;
|
||||
clipOutlinePaint.setAntiAlias(true);
|
||||
clipOutlinePaint.setColor(0x50505050);
|
||||
clipOutlinePaint.setStyle(SkPaint::kStroke_Style);
|
||||
clipOutlinePaint.setStrokeWidth(0);
|
||||
|
||||
if (doLayer) {
|
||||
SkRect bounds;
|
||||
clip->getBounds(&bounds);
|
||||
bounds.outset(2, 2);
|
||||
bounds.offset(x, y);
|
||||
canvas->saveLayer(&bounds, NULL);
|
||||
} else {
|
||||
canvas->save();
|
||||
}
|
||||
canvas->translate(x, y);
|
||||
SkPath closedClipPath;
|
||||
clip->asClosedPath(&closedClipPath);
|
||||
canvas->drawPath(closedClipPath, clipOutlinePaint);
|
||||
clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
|
||||
canvas->scale(1.f, 1.8f);
|
||||
canvas->drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1,
|
||||
0, 1.5f * txtPaint.getTextSize(),
|
||||
txtPaint);
|
||||
canvas->restore();
|
||||
x += textW + 2 * kMargin;
|
||||
}
|
||||
y += fBmp.height() + kMargin;
|
||||
}
|
||||
for (int aa = 0; aa < 2; ++aa) {
|
||||
static const char kTxt[] = "Clip Me!";
|
||||
SkPaint txtPaint;
|
||||
txtPaint.setTextSize(23.f);
|
||||
txtPaint.setAntiAlias(true);
|
||||
txtPaint.setColor(SK_ColorDKGRAY);
|
||||
|
||||
SkPaint clipOutlinePaint;
|
||||
clipOutlinePaint.setAntiAlias(true);
|
||||
clipOutlinePaint.setColor(0x50505050);
|
||||
clipOutlinePaint.setStyle(SkPaint::kStroke_Style);
|
||||
clipOutlinePaint.setStrokeWidth(0);
|
||||
|
||||
canvas->save();
|
||||
canvas->translate(x, y);
|
||||
SkPath closedClipPath;
|
||||
clip->asClosedPath(&closedClipPath);
|
||||
canvas->drawPath(closedClipPath, clipOutlinePaint);
|
||||
clip->setOnCanvas(canvas, SkRegion::kIntersect_Op, SkToBool(aa));
|
||||
canvas->scale(1.f, 1.8f);
|
||||
canvas->drawText(kTxt, SK_ARRAY_COUNT(kTxt)-1,
|
||||
0, 1.5f * txtPaint.getTextSize(),
|
||||
txtPaint);
|
||||
canvas->restore();
|
||||
x += fBmp.width() + kMargin;
|
||||
}
|
||||
|
||||
y += fBmp.height() + kMargin;
|
||||
y = 0;
|
||||
startX += 2 * fBmp.width() + SkScalarCeilToInt(2 * textW) + 6 * kMargin;
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,6 +270,20 @@ private:
|
||||
|
||||
ClipType getType() const { return fClipType; }
|
||||
|
||||
void getBounds(SkRect* bounds) const {
|
||||
switch (fClipType) {
|
||||
case kPath_ClipType:
|
||||
*bounds = fPath.getBounds();
|
||||
break;
|
||||
case kRect_ClipType:
|
||||
*bounds = fRect;
|
||||
break;
|
||||
case kNone_ClipType:
|
||||
SkDEBUGFAIL("Uninitialized Clip.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ClipType fClipType;
|
||||
SkPath fPath;
|
||||
|
@ -11,6 +11,7 @@ using namespace skiagm;
|
||||
SkString GM::gResourcePath;
|
||||
|
||||
GM::GM() {
|
||||
fMode = kGM_Mode;
|
||||
fBGColor = SK_ColorWHITE;
|
||||
fCanvasIsDeferred = false;
|
||||
fHaveCalledOnceBeforeDraw = false;
|
||||
|
18
gm/gm.h
18
gm/gm.h
@ -53,6 +53,15 @@ namespace skiagm {
|
||||
kAsBench_Flag = 1 << 10, // Run the GM as a benchmark in the bench tool
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
kGM_Mode,
|
||||
kSample_Mode,
|
||||
kBench_Mode,
|
||||
};
|
||||
|
||||
void setMode(Mode mode) { fMode = mode; }
|
||||
Mode getMode() const { return fMode; }
|
||||
|
||||
void draw(SkCanvas*);
|
||||
void drawBackground(SkCanvas*);
|
||||
void drawContent(SkCanvas*);
|
||||
@ -101,10 +110,10 @@ namespace skiagm {
|
||||
fCanvasIsDeferred = isDeferred;
|
||||
}
|
||||
|
||||
const SkMatrix& getStarterMatrix() { return fStarterMatrix; }
|
||||
void setStarterMatrix(const SkMatrix& matrix) {
|
||||
fStarterMatrix = matrix;
|
||||
}
|
||||
const SkMatrix& getStarterMatrix() { return fStarterMatrix; }
|
||||
void setStarterMatrix(const SkMatrix& matrix) {
|
||||
fStarterMatrix = matrix;
|
||||
}
|
||||
|
||||
protected:
|
||||
static SkString gResourcePath;
|
||||
@ -118,6 +127,7 @@ namespace skiagm {
|
||||
virtual SkMatrix onGetInitialTransform() const { return SkMatrix::I(); }
|
||||
|
||||
private:
|
||||
Mode fMode;
|
||||
SkString fShortName;
|
||||
SkColor fBGColor;
|
||||
bool fCanvasIsDeferred; // work-around problem in srcmode.cpp
|
||||
|
@ -386,7 +386,9 @@ SkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func)
|
||||
}
|
||||
|
||||
SkView* SkGMSampleViewFactory::operator() () const {
|
||||
return new GMSampleView(fFunc(NULL));
|
||||
skiagm::GM* gm = fFunc(NULL);
|
||||
gm->setMode(skiagm::GM::kSample_Mode);
|
||||
return new GMSampleView(gm);
|
||||
}
|
||||
|
||||
SkViewRegister* SkViewRegister::gHead;
|
||||
|
@ -158,18 +158,23 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
|
||||
// clips against the edges.
|
||||
if (1 == elements.count() && SkClipStack::Element::kPath_Type == elements.tail()->getType() &&
|
||||
SkRegion::kReplace_Op == elements.tail()->getOp()) {
|
||||
const SkPath& p = elements.tail()->getPath();
|
||||
const SkPath& path = elements.tail()->getPath();
|
||||
bool isAA = GR_AA_CLIP && elements.tail()->isAA();
|
||||
SkAutoTUnref<GrEffectRef> effect;
|
||||
if (rt->isMultisampled()) {
|
||||
// A coverage effect for AA clipping won't play nicely with MSAA.
|
||||
if (!isAA) {
|
||||
effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect::kFillNoAA_EdgeType, p));
|
||||
SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
|
||||
SkIntToScalar(-clipDataIn->fOrigin.fY) };
|
||||
effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect::kFillNoAA_EdgeType,
|
||||
path, &offset));
|
||||
}
|
||||
} else {
|
||||
SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
|
||||
SkIntToScalar(-clipDataIn->fOrigin.fY) };
|
||||
GrConvexPolyEffect::EdgeType type = isAA ? GrConvexPolyEffect::kFillAA_EdgeType :
|
||||
GrConvexPolyEffect::kFillNoAA_EdgeType;
|
||||
effect.reset(GrConvexPolyEffect::Create(type, p));
|
||||
effect.reset(GrConvexPolyEffect::Create(type, path, &offset));
|
||||
}
|
||||
if (effect) {
|
||||
are->set(fGpu->drawState());
|
||||
|
@ -97,7 +97,7 @@ GrGLEffect::EffectKey GrGLConvexPolyEffect::GenKey(const GrDrawEffect& drawEffec
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path) {
|
||||
GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path, const SkVector* offset) {
|
||||
if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
|
||||
!path.isConvex() ||
|
||||
path.isInverseFillType()) {
|
||||
@ -114,6 +114,13 @@ GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path) {
|
||||
SkPath::Direction dir;
|
||||
SkAssertResult(path.cheapComputeDirection(&dir));
|
||||
|
||||
SkVector t;
|
||||
if (NULL == offset) {
|
||||
t.set(0, 0);
|
||||
} else {
|
||||
t = *offset;
|
||||
}
|
||||
|
||||
int count = path.getPoints(pts, kMaxEdges);
|
||||
int n = 0;
|
||||
for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) {
|
||||
@ -127,7 +134,8 @@ GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path) {
|
||||
edges[3 * n] = -v.fY;
|
||||
edges[3 * n + 1] = v.fX;
|
||||
}
|
||||
edges[3 * n + 2] = -(edges[3 * n] * pts[i].fX + edges[3 * n + 1] * pts[i].fY);
|
||||
SkPoint p = pts[i] + t;
|
||||
edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,10 @@ public:
|
||||
|
||||
/**
|
||||
* Creates an effect that clips against the path. If the path is not a convex polygon, is
|
||||
* inverse filled, or has too many edges, this will return NULL.
|
||||
* inverse filled, or has too many edges, this will return NULL. If offset is non-NULL, then
|
||||
* the path is translated by the vector.
|
||||
*/
|
||||
static GrEffectRef* Create(EdgeType, const SkPath&);
|
||||
static GrEffectRef* Create(EdgeType, const SkPath&, const SkVector* offset= NULL);
|
||||
|
||||
virtual ~GrConvexPolyEffect();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user