diff options
author | vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-02-24 00:21:06 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-02-24 00:21:06 +0000 |
commit | d3ae77965e94e0efda496f5461cbec4533cb5b16 (patch) | |
tree | 65846e05c8dcba5d1cec2bc64e02ac233c62ffde /src/effects | |
parent | 7d7ca79c3e6e6be7b7849b0d9a7fe26effb89c38 (diff) |
Add asAGradient shader extraction API.
Store initial gradient parameters.
Add compile asserts in GPU code for BitmapType ordering.
Review URL: http://codereview.appspot.com/4178063
git-svn-id: http://skia.googlecode.com/svn/trunk@845 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkGradientShader.cpp | 181 |
1 files changed, 146 insertions, 35 deletions
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp index 64a78c7f0e..41b97cc4c3 100644 --- a/src/effects/SkGradientShader.cpp +++ b/src/effects/SkGradientShader.cpp @@ -129,6 +129,7 @@ protected: SkMallocPixelRef* fCache32PixelRef; void commonAsABitmap(SkBitmap*); + void commonAsAGradient(GradientInfo*) const; private: enum { @@ -687,6 +688,28 @@ void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) { } } +void Gradient_Shader::commonAsAGradient(GradientInfo* info) const { + if (info) { + if (info->fColorCount >= fColorCount) { + if (info->fColors) { + memcpy(info->fColors, fOrigColors, + fColorCount * sizeof(SkColor)); + } + if (info->fColorOffsets) { + if (fColorCount == 2) { + info->fColorOffsets[0] = 0; + info->fColorOffsets[1] = SK_Scalar1; + } else if (fColorCount > 2) { + for (int i = 0; i < fColorCount; i++) + info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos); + } + } + } + info->fColorCount = fColorCount; + info->fTileMode = fTileMode; + } +} + /////////////////////////////////////////////////////////////////////////// static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) { @@ -707,7 +730,9 @@ public: Linear_Gradient(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fStart(pts[0]), + fEnd(pts[1]) { pts_to_unit_matrix(pts, &fPtsToUnit); } @@ -717,17 +742,32 @@ public: virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count); virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*, SkScalar* twoPointRadialParams); + virtual GradientType asAGradient(GradientInfo* info) const; static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Linear_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fStart.fX); + buffer.writeScalar(fStart.fY); + buffer.writeScalar(fEnd.fX); + buffer.writeScalar(fEnd.fY); + } + protected: - Linear_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} + Linear_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fStart(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fEnd(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) { + } virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fStart; + const SkPoint fEnd; }; bool Linear_Gradient::setContext(const SkBitmap& device, const SkPaint& paint, @@ -850,6 +890,15 @@ SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap, return kDefault_BitmapType; } +SkShader::GradientType Linear_Gradient::asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fStart; + info->fPoint[1] = fEnd; + } + return kLinear_GradientType; +} + static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int count) { if (reinterpret_cast<uintptr_t>(dst) & 2) { @@ -989,7 +1038,9 @@ public: Radial_Gradient(const SkPoint& center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fCenter(center), + fRadius(radius) { // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); @@ -1199,17 +1250,38 @@ public: } return kRadial_BitmapType; } + virtual GradientType asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fCenter; + info->fRadius[0] = fRadius; + } + return kRadial_GradientType; + } static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Radial_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fCenter.fX); + buffer.writeScalar(fCenter.fY); + buffer.writeScalar(fRadius); + } + protected: - Radial_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {}; + Radial_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fRadius(buffer.readScalar()) { + } virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter; + const SkScalar fRadius; }; /* Two-point radial gradients are specified by two circles, each with a center @@ -1305,20 +1377,12 @@ public: const SkColor colors[], const SkScalar pos[], int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, colorCount, mode, mapper) - { - fDiff = start - end; - fDiffRadius = endRadius - startRadius; - SkScalar inv = SkScalarInvert(fDiffRadius); - fDiff.fX = SkScalarMul(fDiff.fX, inv); - fDiff.fY = SkScalarMul(fDiff.fY, inv); - fStartRadius = SkScalarMul(startRadius, inv); - fSr2D2 = SkScalarSquare(fStartRadius); - fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1; - fOneOverTwoA = SkScalarInvert(fA * 2); - - fPtsToUnit.setTranslate(-start.fX, -start.fY); - fPtsToUnit.postScale(inv, inv); + : Gradient_Shader(colors, pos, colorCount, mode, mapper), + fCenter1(start), + fCenter2(end), + fRadius1(startRadius), + fRadius2(endRadius) { + init(); } virtual BitmapType asABitmap(SkBitmap* bitmap, @@ -1351,6 +1415,17 @@ public: return kTwoPointRadial_BitmapType; } + virtual GradientType asAGradient(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; + } + virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) { SkASSERT(count > 0); @@ -1468,32 +1543,48 @@ public: virtual void flatten(SkFlattenableWriteBuffer& buffer) { this->INHERITED::flatten(buffer); - buffer.writeScalar(fDiff.fX); - buffer.writeScalar(fDiff.fY); - buffer.writeScalar(fStartRadius); - buffer.writeScalar(fDiffRadius); - buffer.writeScalar(fSr2D2); - buffer.writeScalar(fA); - buffer.writeScalar(fOneOverTwoA); + buffer.writeScalar(fCenter1.fX); + buffer.writeScalar(fCenter1.fY); + buffer.writeScalar(fCenter2.fX); + buffer.writeScalar(fCenter2.fY); + buffer.writeScalar(fRadius1); + buffer.writeScalar(fRadius2); } protected: Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer) - : Gradient_Shader(buffer) { - fDiff.fX = buffer.readScalar(); - fDiff.fY = buffer.readScalar(); - fStartRadius = buffer.readScalar(); - fDiffRadius = buffer.readScalar(); - fSr2D2 = buffer.readScalar(); - fA = buffer.readScalar(); - fOneOverTwoA = buffer.readScalar(); + : Gradient_Shader(buffer), + fCenter1(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fCenter2(SkPoint::Make(buffer.readScalar(), buffer.readScalar())), + fRadius1(buffer.readScalar()), + fRadius2(buffer.readScalar()) { + init(); }; virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter1; + const SkPoint fCenter2; + const SkScalar fRadius1; + const SkScalar fRadius2; SkPoint fDiff; SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA; + + void init() { + fDiff = fCenter1 - fCenter2; + fDiffRadius = fRadius2 - fRadius1; + SkScalar inv = SkScalarInvert(fDiffRadius); + 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 = SkScalarInvert(fA * 2); + + fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY); + fPtsToUnit.postScale(inv, inv); + } }; /////////////////////////////////////////////////////////////////////////////// @@ -1502,7 +1593,8 @@ class Sweep_Gradient : public Gradient_Shader { public: Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], int count, SkUnitMapper* mapper) - : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper) + : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper), + fCenter(SkPoint::Make(cx, cy)) { fPtsToUnit.setTranslate(-cx, -cy); } @@ -1526,16 +1618,35 @@ public: return kSweep_BitmapType; } + virtual GradientType asAGradient(GradientInfo* info) const { + if (info) { + commonAsAGradient(info); + info->fPoint[0] = fCenter; + } + return kSweep_GradientType; + } + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Sweep_Gradient, (buffer)); } + virtual void flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fCenter.fX); + buffer.writeScalar(fCenter.fY); + } + protected: - Sweep_Gradient(SkFlattenableReadBuffer& buffer) : Gradient_Shader(buffer) {} + Sweep_Gradient(SkFlattenableReadBuffer& buffer) + : Gradient_Shader(buffer), + fCenter(SkPoint::Make(buffer.readScalar(), buffer.readScalar())) { + } + virtual Factory getFactory() { return CreateProc; } private: typedef Gradient_Shader INHERITED; + const SkPoint fCenter; }; #ifdef COMPUTE_SWEEP_TABLE |