'../samplecode/SampleAARectModes.cpp',
'../samplecode/SampleAll.cpp',
'../samplecode/SampleAnimator.cpp',
+ '../samplecode/SampleAnimBlur.cpp',
'../samplecode/SampleApp.cpp',
'../samplecode/SampleArc.cpp',
'../samplecode/SampleAvoid.cpp',
--- /dev/null
+
+/*
+ * 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 "SampleCode.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorPriv.h"
+#include "SkCanvas.h"
+#include "SkRandom.h"
+
+class AnimBlurView : public SampleView {
+public:
+ AnimBlurView() {
+ }
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onQuery(SkEvent* evt) {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "AnimBlur");
+ return true;
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ virtual void onDrawContent(SkCanvas* canvas) {
+
+ SkScalar blurRadius = SampleCode::GetAnimSinScalar(100 * SK_Scalar1,
+ 4 * SK_Scalar1,
+ 5 * SK_Scalar1);
+
+ SkScalar circleRadius = 3 * SK_Scalar1 +
+ SampleCode::GetAnimSinScalar(150 * SK_Scalar1,
+ 25 * SK_Scalar1,
+ 3 * SK_Scalar1);
+
+ static const SkBlurMaskFilter::BlurStyle gStyles[] = {
+ SkBlurMaskFilter::kNormal_BlurStyle,
+ SkBlurMaskFilter::kInner_BlurStyle,
+ SkBlurMaskFilter::kSolid_BlurStyle,
+ SkBlurMaskFilter::kOuter_BlurStyle,
+ };
+ SkRandom random;
+
+ for (int i = 0; i < SK_ARRAY_COUNT(gStyles); ++i) {
+ SkMaskFilter* mf = SkBlurMaskFilter::Create(blurRadius,
+ gStyles[i],
+ SkBlurMaskFilter::kHighQuality_BlurFlag);
+ SkPaint paint;
+ paint.setMaskFilter(mf)->unref();
+ paint.setColor(random.nextU() | 0xff000000);
+ canvas->drawCircle(200 * SK_Scalar1 + 400 * (i % 2) * SK_Scalar1,
+ 200 * SK_Scalar1 + i / 2 * 400 * SK_Scalar1,
+ circleRadius, paint);
+ }
+ this->inval(NULL);
+ }
+
+private:
+ typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new AnimBlurView; }
+static SkViewRegister reg(MyFactory);
+
return SkDoubleToScalar(value);
}
+SkScalar SampleCode::GetAnimSinScalar(SkScalar amplitude,
+ SkScalar periodInSec,
+ SkScalar phaseInSec) {
+ if (!periodInSec) {
+ return 0;
+ }
+ double t = (double)gAnimTime / 1000.0 + phaseInSec;
+ t *= SkScalarToFloat(2 * SK_ScalarPI) / periodInSec;
+ amplitude = SK_ScalarHalf * amplitude;
+ return SkScalarMul(amplitude, SkDoubleToScalar(sin(t))) + amplitude;
+}
+
GrContext* SampleCode::GetGr() {
return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
}
static SkMSec GetAnimTimeDelta();
static SkScalar GetAnimSecondsDelta();
static SkScalar GetAnimScalar(SkScalar speedPerSec, SkScalar period = 0);
+ // gives a sinusoidal value between 0 and amplitude
+ static SkScalar GetAnimSinScalar(SkScalar amplitude,
+ SkScalar periodInSec,
+ SkScalar phaseInSec = 0);
static GrContext* GetGr();
};
#include "SkMaskFilter.h"
#include "SkBounder.h"
-static GrPathFill skToGrFillType(SkPath::FillType fillType) {
+///////////////////////////////////////////////////////////////////////////////
+
+// helpers for applying mask filters
+namespace {
+
+GrPathFill skToGrFillType(SkPath::FillType fillType) {
switch (fillType) {
case SkPath::kWinding_FillType:
return kWinding_PathFill;
}
}
-static bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
- SkMaskFilter* filter, const SkMatrix& matrix,
- const SkRegion& clip, SkBounder* bounder,
- GrPaint* grp) {
+// We prefer to blur small rect with small radius via CPU.
+#define MIN_GPU_BLUR_SIZE SkIntToScalar(64)
+#define MIN_GPU_BLUR_RADIUS SkIntToScalar(32)
+inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) {
+ if (rect.width() <= MIN_GPU_BLUR_SIZE &&
+ rect.height() <= MIN_GPU_BLUR_SIZE &&
+ radius <= MIN_GPU_BLUR_RADIUS) {
+ return true;
+ }
+ return false;
+}
+
+bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
+ SkMaskFilter* filter, const SkMatrix& matrix,
+ const SkRegion& clip, SkBounder* bounder,
+ GrPaint* grp) {
#ifdef SK_DISABLE_GPU_BLUR
return false;
#endif
if (radius <= 0) {
return false;
}
+
+ SkRect srcRect = path.getBounds();
+ if (shouldDrawBlurWithCPU(srcRect, radius)) {
+ return false;
+ }
+
float sigma = SkScalarToFloat(radius) * BLUR_SIGMA_SCALE;
float sigma3 = sigma * 3.0f;
- SkRect srcRect = path.getBounds();
SkRect clipRect;
clipRect.set(clip.getBounds());
return true;
}
-static bool drawWithMaskFilter(GrContext* context, const SkPath& path,
- SkMaskFilter* filter, const SkMatrix& matrix,
- const SkRegion& clip, SkBounder* bounder,
- GrPaint* grp) {
+bool drawWithMaskFilter(GrContext* context, const SkPath& path,
+ SkMaskFilter* filter, const SkMatrix& matrix,
+ const SkRegion& clip, SkBounder* bounder,
+ GrPaint* grp) {
SkMask srcM, dstM;
if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
return true;
}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable) {