remove redundant/deprecated TwoPointRadial gradiet -- use TwoPointConical

This CL derived from https://codereview.chromium.org/1114243005/

BUG=skia:

Review URL: https://codereview.chromium.org/1117423003
This commit is contained in:
reed 2015-05-04 08:32:51 -07:00 committed by Commit bot
parent f603fb3d0e
commit 71a6cbfc58
23 changed files with 37 additions and 1132 deletions

View File

@ -71,20 +71,6 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
data.fPos, data.fCount);
}
/// Ignores scale
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, float scale) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
}
/// Ignores scale
static SkShader* MakeConical(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, float scale) {
@ -149,7 +135,6 @@ static const struct {
{ MakeLinear, "linear" },
{ MakeRadial, "radial1" },
{ MakeSweep, "sweep" },
{ Make2Radial, "radial2" },
{ MakeConical, "conical" },
{ MakeConicalZeroRad, "conicalZero" },
{ MakeConicalOutside, "conicalOut" },
@ -160,7 +145,6 @@ enum GradType { // these must match the order in gGrads
kLinear_GradType,
kRadial_GradType,
kSweep_GradType,
kRadial2_GradType,
kConical_GradType,
kConicalZero_GradType,
kConicalOut_GradType,
@ -313,9 +297,6 @@ DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kR
DEF_BENCH( return new GradientBench(kSweep_GradType); )
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
DEF_BENCH( return new GradientBench(kRadial2_GradType); )
DEF_BENCH( return new GradientBench(kRadial2_GradType, gGradData[1]); )
DEF_BENCH( return new GradientBench(kRadial2_GradType, gGradData[0], SkShader::kMirror_TileMode); )
DEF_BENCH( return new GradientBench(kConical_GradType); )
DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[1]); )
DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[2]); )

View File

@ -74,7 +74,7 @@ static SkShader* MakeRadial() {
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(center1, (pts[1].fX - pts[0].fX) / 7,
return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
colors, pos, SK_ARRAY_COUNT(colors), tm,
0, &scale);

View File

@ -112,10 +112,10 @@ static SkShader* MakeRadial() {
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
colors, pos, SK_ARRAY_COUNT(colors), tm,
0, &scale);
return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
colors, pos, SK_ARRAY_COUNT(colors), tm,
0, &scale);
}
// Simpler blurred RR test cases where all the radii are the same.

View File

@ -70,11 +70,11 @@ static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm,
0, &localMatrix);
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm,
0, &localMatrix);
}
static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data,
@ -273,9 +273,9 @@ protected:
SkPoint c1;
c1.iset(0, 25);
SkScalar r1 = SkIntToScalar(150);
SkShader* s = SkGradientShader::CreateTwoPointRadial(c0, r0, c1, r1, colors,
pos, SK_ARRAY_COUNT(pos),
SkShader::kClamp_TileMode);
SkShader* s = SkGradientShader::CreateTwoPointConical(c0, r0, c1, r1, colors,
pos, SK_ARRAY_COUNT(pos),
SkShader::kClamp_TileMode);
SkPaint paint;
paint.setShader(s)->unref();
canvas->drawPaint(paint);

View File

@ -51,7 +51,7 @@ static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShade
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);

View File

@ -64,13 +64,13 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader:
return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
}
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
@ -79,7 +79,7 @@ static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShade
typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
static const GradMaker gGradMakers[] = {
MakeLinear, MakeRadial, MakeSweep, Make2Radial
MakeLinear, MakeRadial, MakeSweep, Make2Conical
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -1,112 +0,0 @@
/*
* 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 "SkPaint.h"
#include "SkGradientShader.h"
static void intToScalars(SkScalar dst[], const int src[], int n) {
for (int i = 0; i < n; ++i) {
dst[i] = SkIntToScalar(src[i]);
}
}
static void drawGrad(SkCanvas* canvas, const SkScalar d0[], const SkScalar d1[]) {
const SkRect bounds = SkRect::MakeXYWH(SkIntToScalar(-50),
SkIntToScalar(-50),
SkIntToScalar(200),
SkIntToScalar(100));
SkPoint c0 = { d0[0], d0[1] };
SkScalar r0 = d0[2];
SkPoint c1 = { d1[0], d1[1] };
SkScalar r1 = d1[2];
SkColor colors[] = { SK_ColorGREEN, SK_ColorRED };
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
SkString str;
str.printf("%g,%g,%g %g,%g,%g",
SkScalarToFloat(c0.fX), SkScalarToFloat(c0.fY), SkScalarToFloat(r0),
SkScalarToFloat(c1.fX), SkScalarToFloat(c1.fY), SkScalarToFloat(r1));
canvas->drawText(str.c_str(), str.size(),
bounds.fLeft, bounds.fTop - paint.getTextSize()/2, paint);
paint.setShader(SkGradientShader::CreateTwoPointConical(c0, r0, c1, r1,
colors, NULL, 2,
SkShader::kClamp_TileMode))->unref();
canvas->drawRect(bounds, paint);
paint.setShader(NULL);
paint.setColor(0x66000000);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawCircle(c0.fX, c0.fY, r0, paint);
canvas->drawCircle(c1.fX, c1.fY, r1, paint);
canvas->drawRect(bounds, paint);
}
class TwoPointRadialGM : public skiagm::GM {
public:
TwoPointRadialGM() {}
protected:
SkString onShortName() {
return SkString("twopointconical");
}
SkISize onISize() { return SkISize::Make(480, 780); }
virtual void onDraw(SkCanvas* canvas) {
if (false) {
SkPaint paint;
paint.setColor(SK_ColorBLUE);
canvas->drawRect(
SkRect::MakeWH(SkIntToScalar(this->getISize().fWidth),
SkIntToScalar(this->getISize().fHeight)),
paint);
}
SkPaint paint;
const int R0 = 20;
const int R1 = 40;
const SkScalar DX = SkIntToScalar(250);
const SkScalar DY = SkIntToScalar(130);
canvas->translate(SkIntToScalar(60), SkIntToScalar(70));
static const int gData[] = {
0, 0, R0, 0, 0, R1,
0, 0, R0, 20, 0, R1,
0, 0, R0, 25, 0, R1,
0, 0, R0, 100, 0, R1,
0, 0, R0, 25, 0, R0,
0, 0, R0, 100, 0, R0,
};
int count = SK_ARRAY_COUNT(gData) / 6;
for (int i = 0; i < count; ++i) {
SkScalar data[6];
intToScalars(data, &gData[i * 6], 6);
int n = canvas->save();
drawGrad(canvas, &data[0], &data[3]);
canvas->translate(DX, 0);
drawGrad(canvas, &data[3], &data[0]);
canvas->restoreToCount(n);
canvas->translate(0, DY);
}
}
};
//////////////////////////////////////////////////////////////////////////////
static skiagm::GM* F(void*) { return new TwoPointRadialGM; }
static skiagm::GMRegistry gR(F);

View File

@ -74,8 +74,6 @@
'<(skia_src_path)/effects/gradients/SkLinearGradient.h',
'<(skia_src_path)/effects/gradients/SkRadialGradient.cpp',
'<(skia_src_path)/effects/gradients/SkRadialGradient.h',
'<(skia_src_path)/effects/gradients/SkTwoPointRadialGradient.cpp',
'<(skia_src_path)/effects/gradients/SkTwoPointRadialGradient.h',
'<(skia_src_path)/effects/gradients/SkTwoPointConicalGradient.cpp',
'<(skia_src_path)/effects/gradients/SkTwoPointConicalGradient.h',
'<(skia_src_path)/effects/gradients/SkTwoPointConicalGradient_gpu.cpp',

View File

@ -229,7 +229,6 @@
'../gm/tilemodes_scaled.cpp',
'../gm/tinybitmap.cpp',
'../gm/transparency.cpp',
'../gm/twopointradial.cpp',
'../gm/typeface.cpp',
'../gm/vertices.cpp',
'../gm/verttext.cpp',

View File

@ -246,19 +246,6 @@ public:
// to (0,0) as bitmap x coord, where angle = 0 is
// bitmap left edge of bitmap = 2pi is the
// right edge. Bitmap is 1 pixel tall. No extras
kTwoPointRadial_BitmapType,
//<! Matrix transforms to space where (0,0) is
// the center of the starting circle. The second
// circle will be centered (x, 0) where x may be
// 0. The post-matrix space is normalized such
// that 1 is the second radius - first radius.
// Three extra parameters are returned:
// 0: x-offset of second circle center
// to first.
// 1: radius of first circle in post-matrix
// space
// 2: the second radius minus the first radius
// in pre-transformed space.
kTwoPointConical_BitmapType,
//<! Matrix transforms to space where (0,0) is
// the center of the starting circle. The second
@ -314,7 +301,7 @@ public:
* fPoint[0] and fPoint[1] are the end-points of the gradient
* Radial:
* fPoint[0] and fRadius[0] are the center and radius
* Radial2:
* Conical:
* fPoint[0] and fRadius[0] are the center and radius of the 1st circle
* fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
* Sweep:
@ -326,7 +313,6 @@ public:
kColor_GradientType,
kLinear_GradientType,
kRadial_GradientType,
kRadial2_GradientType,
kSweep_GradientType,
kConical_GradientType,
kLast_GradientType = kConical_GradientType

View File

@ -80,39 +80,6 @@ public:
return CreateRadial(center, radius, colors, pos, count, mode, 0, NULL);
}
/** Returns a shader that generates a radial gradient given the start position, start radius, end position and end radius.
<p />
CreateTwoPointRadial returns a shader with a reference count of 1.
The caller should decrement the shader's reference count when done with the shader.
It is an error for colorCount to be < 2, for startRadius or endRadius to be < 0, or for
startRadius to be equal to endRadius.
@param start The center of the start circle for this gradient
@param startRadius Must be positive. The radius of the start circle for this gradient.
@param end The center of the end circle for this gradient
@param endRadius Must be positive. The radius of the end circle for this gradient.
@param colors The array[count] of colors, to be distributed between the center and edge of the circle
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
each corresponding color in the colors array. If this is NULL,
the the colors are distributed evenly between the center and edge of the circle.
If this is not null, the values must begin with 0, end with 1.0, and
intermediate values must be strictly increasing.
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
@param mode The tiling mode
*/
static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode,
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode) {
return CreateTwoPointRadial(start, startRadius, end, endRadius, colors, pos, count, mode,
0, NULL);
}
/**
* Returns a shader that generates a conical gradient given two circles, or
* returns NULL if the inputs are invalid. The gradient interprets the

View File

@ -11,15 +11,15 @@
#include "SkGradientShader.h"
class TwoPtRadialView : public SampleView {
class TwoPtConicalView : public SampleView {
public:
TwoPtRadialView() {}
TwoPtConicalView() {}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "2PtRadial");
SampleCode::TitleR(evt, "2PtConical");
return true;
}
return this->INHERITED::onQuery(evt);
@ -33,7 +33,7 @@ protected:
SkScalar r0 = 100;
SkPoint c1 = { 100, 100 };
SkScalar r1 = 100;
SkShader* s = SkGradientShader::CreateTwoPointRadial(c0, r0, c1, r1, colors,
SkShader* s = SkGradientShader::CreateTwoPointConical(c0, r0, c1, r1, colors,
NULL, 2,
SkShader::kClamp_TileMode);
@ -48,5 +48,5 @@ private:
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new TwoPtRadialView; }
static SkView* MyFactory() { return new TwoPtConicalView; }
static SkViewRegister reg(MyFactory);

View File

@ -82,24 +82,24 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader:
return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
}
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
}
static SkShader* Make2RadialConcentric(const SkPoint pts[2], const GradData& data,
static SkShader* Make2ConicalConcentric(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm) {
SkPoint center;
center.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center, (pts[1].fX - pts[0].fX) / 7,
center, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
@ -108,7 +108,7 @@ static SkShader* Make2RadialConcentric(const SkPoint pts[2], const GradData& dat
typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
static const GradMaker gGradMakers[] = {
MakeLinear, MakeRadial, MakeSweep, Make2Radial, Make2RadialConcentric
MakeLinear, MakeRadial, MakeSweep, Make2Conical, Make2ConicalConcentric
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -72,13 +72,13 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader:
return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
}
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
@ -87,7 +87,7 @@ static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShade
typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
static const GradMaker gGradMakers[] = {
MakeLinear, MakeRadial, MakeSweep, Make2Radial
MakeLinear, MakeRadial, MakeSweep, Make2Conical
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -197,13 +197,13 @@ static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, SkShader:
return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
}
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
static SkShader* Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
return SkGradientShader::CreateTwoPointConical(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm);
@ -211,7 +211,7 @@ static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data, SkShade
typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm);
static const GradMaker gGradMakers[] = {
MakeLinear, MakeRadial, MakeSweep, Make2Radial
MakeLinear, MakeRadial, MakeSweep, Make2Conical
};
static void gradient_slide(SkCanvas* canvas) {

View File

@ -1044,8 +1044,7 @@ HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
return S_OK;
}
if (SkShader::kRadial2_GradientType == gradientType ||
SkShader::kConical_GradientType == gradientType) {
if (SkShader::kConical_GradientType == gradientType) {
//simple if affine and one is 0, otherwise will have to fake
}
@ -1061,8 +1060,6 @@ HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
&outMatrix,
xy);
switch (bitmapType) {
case SkShader::kNone_BitmapType:
break;
case SkShader::kDefault_BitmapType: {
//TODO: outMatrix??
SkMatrix localMatrix = shader->getLocalMatrix();
@ -1081,9 +1078,6 @@ HRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint,
return S_OK;
}
case SkShader::kRadial_BitmapType:
case SkShader::kSweep_BitmapType:
case SkShader::kTwoPointRadial_BitmapType:
default:
break;
}

View File

@ -8,7 +8,6 @@
#include "SkGradientShaderPriv.h"
#include "SkLinearGradient.h"
#include "SkRadialGradient.h"
#include "SkTwoPointRadialGradient.h"
#include "SkTwoPointConicalGradient.h"
#include "SkSweepGradient.h"
@ -802,30 +801,6 @@ SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius,
return SkNEW_ARGS(SkRadialGradient, (center, radius, desc));
}
SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start,
SkScalar startRadius,
const SkPoint& end,
SkScalar endRadius,
const SkColor colors[],
const SkScalar pos[],
int colorCount,
SkShader::TileMode mode,
uint32_t flags,
const SkMatrix* localMatrix) {
if (startRadius < 0 || endRadius < 0) {
return NULL;
}
if (!valid_grad(colors, pos, colorCount, mode)) {
return NULL;
}
EXPAND_1_COLOR(colorCount);
SkGradientShaderBase::Descriptor desc;
desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix);
return SkNEW_ARGS(SkTwoPointRadialGradient,
(start, startRadius, end, endRadius, desc));
}
SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start,
SkScalar startRadius,
const SkPoint& end,
@ -897,7 +872,6 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointRadialGradient)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient)
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END

View File

@ -1,724 +0,0 @@
/*
* 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 "SkTwoPointRadialGradient.h"
/* Two-point radial gradients are specified by two circles, each with a center
point and radius. The gradient can be considered to be a series of
concentric circles, with the color interpolated from the start circle
(at t=0) to the end circle (at t=1).
For each point (x, y) in the span, we want to find the
interpolated circle that intersects that point. The center
of the desired circle (Cx, Cy) falls at some distance t
along the line segment between the start point (Sx, Sy) and
end point (Ex, Ey):
Cx = (1 - t) * Sx + t * Ex (0 <= t <= 1)
Cy = (1 - t) * Sy + t * Ey
The radius of the desired circle (r) is also a linear interpolation t
between the start and end radii (Sr and Er):
r = (1 - t) * Sr + t * Er
But
(x - Cx)^2 + (y - Cy)^2 = r^2
so
(x - ((1 - t) * Sx + t * Ex))^2
+ (y - ((1 - t) * Sy + t * Ey))^2
= ((1 - t) * Sr + t * Er)^2
Solving for t yields
[(Sx - Ex)^2 + (Sy - Ey)^2 - (Er - Sr)^2)] * t^2
+ [2 * (Sx - Ex)(x - Sx) + 2 * (Sy - Ey)(y - Sy) - 2 * (Er - Sr) * Sr] * t
+ [(x - Sx)^2 + (y - Sy)^2 - Sr^2] = 0
To simplify, let Dx = Sx - Ex, Dy = Sy - Ey, Dr = Er - Sr, dx = x - Sx, dy = y - Sy
[Dx^2 + Dy^2 - Dr^2)] * t^2
+ 2 * [Dx * dx + Dy * dy - Dr * Sr] * t
+ [dx^2 + dy^2 - Sr^2] = 0
A quadratic in t. The two roots of the quadratic reflect the two
possible circles on which the point may fall. Solving for t yields
the gradient value to use.
If a<0, the start circle is entirely contained in the
end circle, and one of the roots will be <0 or >1 (off the line
segment). If a>0, the start circle falls at least partially
outside the end circle (or vice versa), and the gradient
defines a "tube" where a point may be on one circle (on the
inside of the tube) or the other (outside of the tube). We choose
one arbitrarily.
In order to keep the math to within the limits of fixed point,
we divide the entire quadratic by Dr^2, and replace
(x - Sx)/Dr with x' and (y - Sy)/Dr with y', giving
[Dx^2 / Dr^2 + Dy^2 / Dr^2 - 1)] * t^2
+ 2 * [x' * Dx / Dr + y' * Dy / Dr - Sr / Dr] * t
+ [x'^2 + y'^2 - Sr^2/Dr^2] = 0
(x' and y' are computed by appending the subtract and scale to the
fDstToIndex matrix in the constructor).
Since the 'A' component of the quadratic is independent of x' and y', it
is precomputed in the constructor. Since the 'B' component is linear in
x' and y', if x and y are linear in the span, 'B' can be computed
incrementally with a simple delta (db below). If it is not (e.g.,
a perspective projection), it must be computed in the loop.
*/
namespace {
inline SkFixed two_point_radial(SkScalar b, SkScalar fx, SkScalar fy,
SkScalar sr2d2, SkScalar foura,
SkScalar oneOverTwoA, bool posRoot) {
SkScalar c = SkScalarSquare(fx) + SkScalarSquare(fy) - sr2d2;
if (0 == foura) {
return SkScalarToFixed(SkScalarDiv(-c, b));
}
SkScalar discrim = SkScalarSquare(b) - SkScalarMul(foura, c);
if (discrim < 0) {
discrim = -discrim;
}
SkScalar rootDiscrim = SkScalarSqrt(discrim);
SkScalar result;
if (posRoot) {
result = SkScalarMul(-b + rootDiscrim, oneOverTwoA);
} else {
result = SkScalarMul(-b - rootDiscrim, oneOverTwoA);
}
return SkScalarToFixed(result);
}
typedef void (* TwoPointRadialShadeProc)(SkScalar fx, SkScalar dx,
SkScalar fy, SkScalar dy,
SkScalar b, SkScalar db,
SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count);
void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
SkScalar fy, SkScalar dy,
SkScalar b, SkScalar db,
SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
fOneOverTwoA, posRoot);
SkFixed index = SkClampMax(t, 0xFFFF);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
fx += dx;
fy += dy;
b += db;
}
}
void shadeSpan_twopoint_mirror(SkScalar fx, SkScalar dx,
SkScalar fy, SkScalar dy,
SkScalar b, SkScalar db,
SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
fOneOverTwoA, posRoot);
SkFixed index = mirror_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
fx += dx;
fy += dy;
b += db;
}
}
void shadeSpan_twopoint_repeat(SkScalar fx, SkScalar dx,
SkScalar fy, SkScalar dy,
SkScalar b, SkScalar db,
SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
int count) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
fOneOverTwoA, posRoot);
SkFixed index = repeat_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
fx += dx;
fy += dy;
b += db;
}
}
}
/////////////////////////////////////////////////////////////////////
static SkMatrix pts_to_unit(const SkPoint& start, SkScalar diffRadius) {
SkScalar inv = diffRadius ? SkScalarInvert(diffRadius) : 0;
SkMatrix matrix;
matrix.setTranslate(-start.fX, -start.fY);
matrix.postScale(inv, inv);
return matrix;
}
SkTwoPointRadialGradient::SkTwoPointRadialGradient(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const Descriptor& desc)
: SkGradientShaderBase(desc, pts_to_unit(start, endRadius - startRadius))
, fCenter1(start)
, fCenter2(end)
, fRadius1(startRadius)
, fRadius2(endRadius)
{
fDiff = fCenter1 - fCenter2;
fDiffRadius = fRadius2 - fRadius1;
// hack to avoid zero-divide for now
SkScalar inv = fDiffRadius ? SkScalarInvert(fDiffRadius) : 0;
fDiff.fX = SkScalarMul(fDiff.fX, inv);
fDiff.fY = SkScalarMul(fDiff.fY, inv);
fStartRadius = SkScalarMul(fRadius1, inv);
fSr2D2 = SkScalarSquare(fStartRadius);
fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
}
SkShader::BitmapType SkTwoPointRadialGradient::asABitmap(
SkBitmap* bitmap,
SkMatrix* matrix,
SkShader::TileMode* xy) const {
if (bitmap) {
this->getGradientTableBitmap(bitmap);
}
SkScalar diffL = 0; // just to avoid gcc warning
if (matrix) {
diffL = SkScalarSqrt(SkScalarSquare(fDiff.fX) +
SkScalarSquare(fDiff.fY));
}
if (matrix) {
if (diffL) {
SkScalar invDiffL = SkScalarInvert(diffL);
matrix->setSinCos(-SkScalarMul(invDiffL, fDiff.fY),
SkScalarMul(invDiffL, fDiff.fX));
} else {
matrix->reset();
}
matrix->preConcat(fPtsToUnit);
}
if (xy) {
xy[0] = fTileMode;
xy[1] = kClamp_TileMode;
}
return kTwoPointRadial_BitmapType;
}
SkShader::GradientType SkTwoPointRadialGradient::asAGradient(
SkShader::GradientInfo* info) const {
if (info) {
commonAsAGradient(info);
info->fPoint[0] = fCenter1;
info->fPoint[1] = fCenter2;
info->fRadius[0] = fRadius1;
info->fRadius[1] = fRadius2;
}
return kRadial2_GradientType;
}
size_t SkTwoPointRadialGradient::contextSize() const {
return sizeof(TwoPointRadialGradientContext);
}
SkShader::Context* SkTwoPointRadialGradient::onCreateContext(const ContextRec& rec,
void* storage) const {
// For now, we might have divided by zero, so detect that.
if (0 == fDiffRadius) {
return NULL;
}
return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext, (*this, rec));
}
SkTwoPointRadialGradient::TwoPointRadialGradientContext::TwoPointRadialGradientContext(
const SkTwoPointRadialGradient& shader, const ContextRec& rec)
: INHERITED(shader, rec)
{
// we don't have a span16 proc
fFlags &= ~kHasSpan16_Flag;
}
void SkTwoPointRadialGradient::TwoPointRadialGradientContext::shadeSpan(
int x, int y, SkPMColor* dstCParam, int count) {
SkASSERT(count > 0);
const SkTwoPointRadialGradient& twoPointRadialGradient =
static_cast<const SkTwoPointRadialGradient&>(fShader);
SkPMColor* SK_RESTRICT dstC = dstCParam;
// Zero difference between radii: fill with transparent black.
if (twoPointRadialGradient.fDiffRadius == 0) {
sk_bzero(dstC, count * sizeof(*dstC));
return;
}
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = twoPointRadialGradient.fTileProc;
const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
SkScalar foura = twoPointRadialGradient.fA * 4;
bool posRoot = twoPointRadialGradient.fDiffRadius < 0;
if (fDstToIndexClass != kPerspective_MatrixClass) {
SkPoint srcPt;
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkScalar dx, fx = srcPt.fX;
SkScalar dy, fy = srcPt.fY;
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed fixedX, fixedY;
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
dx = SkFixedToScalar(fixedX);
dy = SkFixedToScalar(fixedY);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = fDstToIndex.getScaleX();
dy = fDstToIndex.getSkewY();
}
SkScalar b = (SkScalarMul(twoPointRadialGradient.fDiff.fX, fx) +
SkScalarMul(twoPointRadialGradient.fDiff.fY, fy) -
twoPointRadialGradient.fStartRadius) * 2;
SkScalar db = (SkScalarMul(twoPointRadialGradient.fDiff.fX, dx) +
SkScalarMul(twoPointRadialGradient.fDiff.fY, dy)) * 2;
TwoPointRadialShadeProc shadeProc = shadeSpan_twopoint_repeat;
if (SkShader::kClamp_TileMode == twoPointRadialGradient.fTileMode) {
shadeProc = shadeSpan_twopoint_clamp;
} else if (SkShader::kMirror_TileMode == twoPointRadialGradient.fTileMode) {
shadeProc = shadeSpan_twopoint_mirror;
} else {
SkASSERT(SkShader::kRepeat_TileMode == twoPointRadialGradient.fTileMode);
}
(*shadeProc)(fx, dx, fy, dy, b, db,
twoPointRadialGradient.fSr2D2, foura,
twoPointRadialGradient.fOneOverTwoA, posRoot,
dstC, cache, count);
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
for (; count > 0; --count) {
SkPoint srcPt;
dstProc(fDstToIndex, dstX, dstY, &srcPt);
SkScalar fx = srcPt.fX;
SkScalar fy = srcPt.fY;
SkScalar b = (SkScalarMul(twoPointRadialGradient.fDiff.fX, fx) +
SkScalarMul(twoPointRadialGradient.fDiff.fY, fy) -
twoPointRadialGradient.fStartRadius) * 2;
SkFixed t = two_point_radial(b, fx, fy, twoPointRadialGradient.fSr2D2, foura,
twoPointRadialGradient.fOneOverTwoA, posRoot);
SkFixed index = proc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
dstX += SK_Scalar1;
}
}
}
#ifndef SK_IGNORE_TO_STRING
void SkTwoPointRadialGradient::toString(SkString* str) const {
str->append("SkTwoPointRadialGradient: (");
str->append("center1: (");
str->appendScalar(fCenter1.fX);
str->append(", ");
str->appendScalar(fCenter1.fY);
str->append(") radius1: ");
str->appendScalar(fRadius1);
str->append(" ");
str->append("center2: (");
str->appendScalar(fCenter2.fX);
str->append(", ");
str->appendScalar(fCenter2.fY);
str->append(") radius2: ");
str->appendScalar(fRadius2);
str->append(" ");
this->INHERITED::toString(str);
str->append(")");
}
#endif
SkFlattenable* SkTwoPointRadialGradient::CreateProc(SkReadBuffer& buffer) {
DescriptorScope desc;
if (!desc.unflatten(buffer)) {
return NULL;
}
const SkPoint c1 = buffer.readPoint();
const SkPoint c2 = buffer.readPoint();
const SkScalar r1 = buffer.readScalar();
const SkScalar r2 = buffer.readScalar();
return SkGradientShader::CreateTwoPointRadial(c1, r1, c2, r2, desc.fColors, desc.fPos,
desc.fCount, desc.fTileMode, desc.fGradFlags,
desc.fLocalMatrix);
}
void SkTwoPointRadialGradient::flatten(
SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writePoint(fCenter1);
buffer.writePoint(fCenter2);
buffer.writeScalar(fRadius1);
buffer.writeScalar(fRadius2);
}
/////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "SkGr.h"
#include "gl/builders/GrGLProgramBuilder.h"
// For brevity
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
class GrGLRadial2Gradient : public GrGLGradientEffect {
public:
GrGLRadial2Gradient(const GrProcessor&);
virtual ~GrGLRadial2Gradient() { }
virtual void emitCode(GrGLFPBuilder*,
const GrFragmentProcessor&,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray&,
const TextureSamplerArray&) override;
void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
protected:
UniformHandle fParamUni;
const char* fVSVaryingName;
const char* fFSVaryingName;
bool fIsDegenerate;
// @{
/// Values last uploaded as uniforms
SkScalar fCachedCenter;
SkScalar fCachedRadius;
bool fCachedPosRoot;
// @}
private:
typedef GrGLGradientEffect INHERITED;
};
/////////////////////////////////////////////////////////////////////
class GrRadial2Gradient : public GrGradientEffect {
public:
static GrFragmentProcessor* Create(GrContext* ctx,
const SkTwoPointRadialGradient& shader,
const SkMatrix& matrix,
SkShader::TileMode tm) {
return SkNEW_ARGS(GrRadial2Gradient, (ctx, shader, matrix, tm));
}
virtual ~GrRadial2Gradient() { }
const char* name() const override { return "Two-Point Radial Gradient"; }
virtual void getGLProcessorKey(const GrGLSLCaps& caps,
GrProcessorKeyBuilder* b) const override {
GrGLRadial2Gradient::GenKey(*this, caps, b);
}
GrGLFragmentProcessor* createGLInstance() const override {
return SkNEW_ARGS(GrGLRadial2Gradient, (*this));
}
// The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
bool isDegenerate() const { return SK_Scalar1 == fCenterX1; }
SkScalar center() const { return fCenterX1; }
SkScalar radius() const { return fRadius0; }
bool isPosRoot() const { return SkToBool(fPosRoot); }
private:
bool onIsEqual(const GrFragmentProcessor& sBase) const override {
const GrRadial2Gradient& s = sBase.cast<GrRadial2Gradient>();
return (INHERITED::onIsEqual(sBase) &&
this->fCenterX1 == s.fCenterX1 &&
this->fRadius0 == s.fRadius0 &&
this->fPosRoot == s.fPosRoot);
}
GrRadial2Gradient(GrContext* ctx,
const SkTwoPointRadialGradient& shader,
const SkMatrix& matrix,
SkShader::TileMode tm)
: INHERITED(ctx, shader, matrix, tm)
, fCenterX1(shader.getCenterX1())
, fRadius0(shader.getStartRadius())
, fPosRoot(shader.getDiffRadius() < 0) {
this->initClassID<GrRadial2Gradient>();
// We pass the linear part of the quadratic as a varying.
// float b = 2.0 * (fCenterX1 * x - fRadius0 * z)
fBTransform = this->getCoordTransform();
SkMatrix& bMatrix = *fBTransform.accessMatrix();
bMatrix[SkMatrix::kMScaleX] = 2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMScaleX]) -
SkScalarMul(fRadius0, bMatrix[SkMatrix::kMPersp0]));
bMatrix[SkMatrix::kMSkewX] = 2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMSkewX]) -
SkScalarMul(fRadius0, bMatrix[SkMatrix::kMPersp1]));
bMatrix[SkMatrix::kMTransX] = 2 * (SkScalarMul(fCenterX1, bMatrix[SkMatrix::kMTransX]) -
SkScalarMul(fRadius0, bMatrix[SkMatrix::kMPersp2]));
this->addCoordTransform(&fBTransform);
}
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
// @{
// Cache of values - these can change arbitrarily, EXCEPT
// we shouldn't change between degenerate and non-degenerate?!
GrCoordTransform fBTransform;
SkScalar fCenterX1;
SkScalar fRadius0;
SkBool8 fPosRoot;
// @}
typedef GrGradientEffect INHERITED;
};
/////////////////////////////////////////////////////////////////////
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRadial2Gradient);
GrFragmentProcessor* GrRadial2Gradient::TestCreate(SkRandom* random,
GrContext* context,
const GrDrawTargetCaps&,
GrTexture**) {
SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
SkScalar radius1 = random->nextUScalar1();
SkPoint center2;
SkScalar radius2;
do {
center2.set(random->nextUScalar1(), random->nextUScalar1());
radius2 = random->nextUScalar1 ();
// There is a bug in two point radial gradients with identical radii
} while (radius1 == radius2);
SkColor colors[kMaxRandomGradientColors];
SkScalar stopsArray[kMaxRandomGradientColors];
SkScalar* stops = stopsArray;
SkShader::TileMode tm;
int colorCount = RandomGradientParams(random, colors, &stops, &tm);
SkAutoTUnref<SkShader> shader(SkGradientShader::CreateTwoPointRadial(center1, radius1,
center2, radius2,
colors, stops, colorCount,
tm));
SkPaint paint;
GrFragmentProcessor* fp;
GrColor paintColor;
SkAssertResult(shader->asFragmentProcessor(context, paint,
GrTest::TestMatrix(random), NULL,
&paintColor, &fp));
return fp;
}
/////////////////////////////////////////////////////////////////////
GrGLRadial2Gradient::GrGLRadial2Gradient(const GrProcessor& processor)
: fVSVaryingName(NULL)
, fFSVaryingName(NULL)
, fCachedCenter(SK_ScalarMax)
, fCachedRadius(-SK_ScalarMax)
, fCachedPosRoot(0) {
const GrRadial2Gradient& data = processor.cast<GrRadial2Gradient>();
fIsDegenerate = data.isDegenerate();
}
void GrGLRadial2Gradient::emitCode(GrGLFPBuilder* builder,
const GrFragmentProcessor& fp,
const char* outputColor,
const char* inputColor,
const TransformedCoordsArray& coords,
const TextureSamplerArray& samplers) {
const GrRadial2Gradient& ge = fp.cast<GrRadial2Gradient>();
this->emitUniforms(builder, ge);
fParamUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision,
"Radial2FSParams", 6);
SkString cName("c");
SkString ac4Name("ac4");
SkString rootName("root");
SkString t;
SkString p0;
SkString p1;
SkString p2;
SkString p3;
SkString p4;
SkString p5;
builder->getUniformVariable(fParamUni).appendArrayAccess(0, &p0);
builder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
builder->getUniformVariable(fParamUni).appendArrayAccess(2, &p2);
builder->getUniformVariable(fParamUni).appendArrayAccess(3, &p3);
builder->getUniformVariable(fParamUni).appendArrayAccess(4, &p4);
builder->getUniformVariable(fParamUni).appendArrayAccess(5, &p5);
GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
// We interpolate the linear component in coords[1].
SkASSERT(coords[0].getType() == coords[1].getType());
const char* coords2D;
SkString bVar;
if (kVec3f_GrSLType == coords[0].getType()) {
fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy, %s.x) / %s.z;\n",
coords[0].c_str(), coords[1].c_str(), coords[0].c_str());
coords2D = "interpolants.xy";
bVar = "interpolants.z";
} else {
coords2D = coords[0].c_str();
bVar.printf("%s.x", coords[1].c_str());
}
// c = (x^2)+(y^2) - params[4]
fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(), coords2D, coords2D, p4.c_str());
// If we aren't degenerate, emit some extra code, and accept a slightly
// more complex coord.
if (!fIsDegenerate) {
// ac4 = 4.0 * params[0] * c
fsBuilder->codeAppendf("\tfloat %s = %s * 4.0 * %s;\n",
ac4Name.c_str(), p0.c_str(),
cName.c_str());
// root = sqrt(b^2-4ac)
// (abs to avoid exception due to fp precision)
fsBuilder->codeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
rootName.c_str(), bVar.c_str(), bVar.c_str(),
ac4Name.c_str());
// t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(),
rootName.c_str(), p1.c_str());
} else {
// t is: -c/b
t.printf("-%s / %s", cName.c_str(), bVar.c_str());
}
this->emitColor(builder, ge, t.c_str(), outputColor, inputColor, samplers);
}
void GrGLRadial2Gradient::setData(const GrGLProgramDataManager& pdman,
const GrProcessor& processor) {
INHERITED::setData(pdman, processor);
const GrRadial2Gradient& data = processor.cast<GrRadial2Gradient>();
SkASSERT(data.isDegenerate() == fIsDegenerate);
SkScalar centerX1 = data.center();
SkScalar radius0 = data.radius();
if (fCachedCenter != centerX1 ||
fCachedRadius != radius0 ||
fCachedPosRoot != data.isPosRoot()) {
SkScalar a = SkScalarMul(centerX1, centerX1) - SK_Scalar1;
// When we're in the degenerate (linear) case, the second
// value will be INF but the program doesn't read it. (We
// use the same 6 uniforms even though we don't need them
// all in the linear case just to keep the code complexity
// down).
float values[6] = {
SkScalarToFloat(a),
1 / (2.f * SkScalarToFloat(a)),
SkScalarToFloat(centerX1),
SkScalarToFloat(radius0),
SkScalarToFloat(SkScalarMul(radius0, radius0)),
data.isPosRoot() ? 1.f : -1.f
};
pdman.set1fv(fParamUni, 6, values);
fCachedCenter = centerX1;
fCachedRadius = radius0;
fCachedPosRoot = data.isPosRoot();
}
}
void GrGLRadial2Gradient::GenKey(const GrProcessor& processor,
const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
uint32_t* key = b->add32n(2);
key[0] = GenBaseGradientKey(processor);
key[1] = processor.cast<GrRadial2Gradient>().isDegenerate();
}
/////////////////////////////////////////////////////////////////////
bool SkTwoPointRadialGradient::asFragmentProcessor(GrContext* context, const SkPaint& paint,
const SkMatrix&,
const SkMatrix* localMatrix, GrColor* paintColor,
GrFragmentProcessor** fp) const {
SkASSERT(context);
// invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
SkMatrix matrix;
if (!this->getLocalMatrix().invert(&matrix)) {
return false;
}
if (localMatrix) {
SkMatrix inv;
if (!localMatrix->invert(&inv)) {
return false;
}
matrix.postConcat(inv);
}
matrix.postConcat(fPtsToUnit);
SkScalar diffLen = fDiff.length();
if (0 != diffLen) {
SkScalar invDiffLen = SkScalarInvert(diffLen);
SkMatrix rot;
rot.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY),
SkScalarMul(invDiffLen, fDiff.fX));
matrix.postConcat(rot);
}
*paintColor = SkColor2GrColorJustAlpha(paint.getColor());
*fp = GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
return true;
}
#else
bool SkTwoPointRadialGradient::asFragmentProcessor(GrContext*, const SkPaint&, const SkMatrix&,
const SkMatrix*,
GrColor*, GrFragmentProcessor**) const {
SkDEBUGFAIL("Should not call in GPU-less build");
return false;
}
#endif

View File

@ -1,64 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkTwoPointRadialGradient_DEFINED
#define SkTwoPointRadialGradient_DEFINED
#include "SkGradientShaderPriv.h"
class SkTwoPointRadialGradient : public SkGradientShaderBase {
public:
SkTwoPointRadialGradient(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const Descriptor&);
virtual BitmapType asABitmap(SkBitmap* bitmap,
SkMatrix* matrix,
TileMode* xy) const override;
GradientType asAGradient(GradientInfo* info) const override;
virtual bool asFragmentProcessor(GrContext* context, const SkPaint&, const SkMatrix& viewM,
const SkMatrix*, GrColor*,
GrFragmentProcessor**) const override;
size_t contextSize() const override;
class TwoPointRadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
public:
TwoPointRadialGradientContext(const SkTwoPointRadialGradient&, const ContextRec&);
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
private:
typedef SkGradientShaderBase::GradientShaderBaseContext INHERITED;
};
SkScalar getCenterX1() const { return fDiff.length(); }
SkScalar getStartRadius() const { return fStartRadius; }
SkScalar getDiffRadius() const { return fDiffRadius; }
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTwoPointRadialGradient)
protected:
SkTwoPointRadialGradient(SkReadBuffer& buffer);
void flatten(SkWriteBuffer& buffer) const override;
Context* onCreateContext(const ContextRec&, void* storage) const override;
private:
const SkPoint fCenter1;
const SkPoint fCenter2;
const SkScalar fRadius1;
const SkScalar fRadius2;
SkPoint fDiff;
SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
friend class SkGradientShader;
typedef SkGradientShaderBase INHERITED;
};
#endif

View File

@ -49,7 +49,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
* we verify the count is as expected. If a new factory is added, then these numbers must be
* manually adjusted.
*/
static const int kFPFactoryCount = 38;
static const int kFPFactoryCount = 37;
static const int kGPFactoryCount = 14;
static const int kXPFactoryCount = 5;

View File

@ -347,19 +347,6 @@ void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
///////////////////////////////////////////////////////////////////////////////
SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5,
shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch);
SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch);
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);

View File

@ -290,58 +290,6 @@ static SkString radialCode(const SkShader::GradientInfo& info,
return function;
}
/* The math here is all based on the description in Two_Point_Radial_Gradient,
with one simplification, the coordinate space has been scaled so that
Dr = 1. This means we don't need to scale the entire equation by 1/Dr^2.
*/
static SkString twoPointRadialCode(const SkShader::GradientInfo& info,
const SkMatrix& perspectiveRemover) {
SkScalar dx = info.fPoint[0].fX - info.fPoint[1].fX;
SkScalar dy = info.fPoint[0].fY - info.fPoint[1].fY;
SkScalar sr = info.fRadius[0];
SkScalar a = SkScalarMul(dx, dx) + SkScalarMul(dy, dy) - SK_Scalar1;
bool posRoot = info.fRadius[1] > info.fRadius[0];
// We start with a stack of (x y), copy it and then consume one copy in
// order to calculate b and the other to calculate c.
SkString function("{");
function.append(apply_perspective_to_coordinates(perspectiveRemover));
function.append("2 copy ");
// Calculate -b and b^2.
function.appendScalar(dy);
function.append(" mul exch ");
function.appendScalar(dx);
function.append(" mul add ");
function.appendScalar(sr);
function.append(" sub 2 mul neg dup dup mul\n");
// Calculate c
function.append("4 2 roll dup mul exch dup mul add ");
function.appendScalar(SkScalarMul(sr, sr));
function.append(" sub\n");
// Calculate the determinate
function.appendScalar(SkScalarMul(SkIntToScalar(4), a));
function.append(" mul sub abs sqrt\n");
// And then the final value of t.
if (posRoot) {
function.append("sub ");
} else {
function.append("add ");
}
function.appendScalar(SkScalarMul(SkIntToScalar(2), a));
function.append(" div\n");
tileModeCode(info.fTileMode, &function);
gradientFunctionCode(info, &function);
function.append("}");
return function;
}
/* Conical gradient shader, based on the Canvas spec for radial gradients
See: http://www.w3.org/TR/2dcontext/#dom-context-2d-createradialgradient
*/
@ -782,17 +730,6 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create(
transformPoints[1].fX += info->fRadius[0];
codeFunction = &radialCode;
break;
case SkShader::kRadial2_GradientType: {
// Bail out if the radii are the same.
if (info->fRadius[0] == info->fRadius[1]) {
return NULL;
}
transformPoints[1] = transformPoints[0];
SkScalar dr = info->fRadius[1] - info->fRadius[0];
transformPoints[1].fX += dr;
codeFunction = &twoPointRadialCode;
break;
}
case SkShader::kConical_GradientType: {
transformPoints[1] = transformPoints[0];
transformPoints[1].fX += SK_Scalar1;
@ -852,7 +789,7 @@ SkPDFFunctionShader* SkPDFFunctionShader::Create(
// state.fInfo
// in translating from x, y coordinates to the t parameter. So, we have
// to transform the points and radii according to the calculated matrix.
if (state.fType == SkShader::kRadial2_GradientType) {
if (state.fType == SkShader::kConical_GradientType) {
SkShader::GradientInfo twoPointRadialInfo = *info;
SkMatrix inverseMapperMatrix;
if (!mapperMatrix.invert(&inverseMapperMatrix)) {
@ -1143,7 +1080,6 @@ bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
return false;
}
break;
case SkShader::kRadial2_GradientType:
case SkShader::kConical_GradientType:
if (fInfo.fPoint[1] != b.fInfo.fPoint[1] ||
fInfo.fRadius[0] != b.fInfo.fRadius[0] ||

View File

@ -107,22 +107,6 @@ static void radial_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
REPORTER_ASSERT(reporter, info.fRadius[0] == rec.fRadius[0]);
}
static void radial2_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
SkAutoTUnref<SkShader> s(SkGradientShader::CreateTwoPointRadial(rec.fPoint[0],
rec.fRadius[0],
rec.fPoint[1],
rec.fRadius[1],
rec.fColors,
rec.fPos,
rec.fColorCount,
rec.fTileMode));
SkShader::GradientInfo info;
rec.gradCheck(reporter, s, &info, SkShader::kRadial2_GradientType);
REPORTER_ASSERT(reporter, !memcmp(info.fPoint, rec.fPoint, 2 * sizeof(SkPoint)));
REPORTER_ASSERT(reporter, !memcmp(info.fRadius, rec.fRadius, 2 * sizeof(SkScalar)));
}
static void sweep_gradproc(skiatest::Reporter* reporter, const GradRec& rec) {
SkAutoTUnref<SkShader> s(SkGradientShader::CreateSweep(rec.fPoint[0].fX,
rec.fPoint[0].fY,
@ -203,7 +187,6 @@ static void TestGradientShaders(skiatest::Reporter* reporter) {
color_gradproc,
linear_gradproc,
radial_gradproc,
radial2_gradproc,
sweep_gradproc,
conical_gradproc,
};