diff options
author | deanm@chromium.org <deanm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 12:50:58 +0000 |
---|---|---|
committer | deanm@chromium.org <deanm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 12:50:58 +0000 |
commit | 9a136cdf89222c11b0dae86e19ff0b14956f929a (patch) | |
tree | 44f007a586303dce4a7a7024fd785eee22da61fe /skia/sgl | |
parent | e91a73a43d79d437c59a5a44396e919628f3f707 (diff) | |
download | chromium_src-9a136cdf89222c11b0dae86e19ff0b14956f929a.zip chromium_src-9a136cdf89222c11b0dae86e19ff0b14956f929a.tar.gz chromium_src-9a136cdf89222c11b0dae86e19ff0b14956f929a.tar.bz2 |
Integrate change of Skia upstream.
This is a cherry-pick of the following change:
http://code.google.com/p/skia/source/detail?r=159
We introduce this change for the 'lighter' composite operation. We need kAdd_Mode, which is introduced in this change for the operation.
Patch by Shinichiro Hamaji.
BUG=1619
Review URL: http://codereview.chromium.org/93093
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14938 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/sgl')
-rw-r--r-- | skia/sgl/SkDraw.cpp | 14 | ||||
-rw-r--r-- | skia/sgl/SkMask.cpp | 42 | ||||
-rw-r--r-- | skia/sgl/SkXfermode.cpp | 29 |
3 files changed, 51 insertions, 34 deletions
diff --git a/skia/sgl/SkDraw.cpp b/skia/sgl/SkDraw.cpp index 2f0ddff..40b9026 100644 --- a/skia/sgl/SkDraw.cpp +++ b/skia/sgl/SkDraw.cpp @@ -911,11 +911,16 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, return; } } + mask.fFormat = SkMask::kA8_Format; mask.fRowBytes = SkAlign4(mask.fBounds.width()); + size_t size = mask.computeImageSize(); + if (0 == size) { + // the mask is too big to allocated, draw nothing + return; + } // allocate (and clear) our temp buffer to hold the transformed bitmap - size_t size = mask.computeImageSize(); SkAutoMalloc storage(size); mask.fImage = (uint8_t*)storage.get(); memset(mask.fImage, 0, size); @@ -2336,7 +2341,12 @@ bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) { mask->fFormat = SkMask::kA8_Format; mask->fRowBytes = mask->fBounds.width(); - mask->fImage = SkMask::AllocImage(mask->computeImageSize()); + size_t size = mask->computeImageSize(); + if (0 == size) { + // we're too big to allocate the mask, abort + return false; + } + mask->fImage = SkMask::AllocImage(size); memset(mask->fImage, 0, mask->computeImageSize()); } diff --git a/skia/sgl/SkMask.cpp b/skia/sgl/SkMask.cpp index 1a03b16..337204b 100644 --- a/skia/sgl/SkMask.cpp +++ b/skia/sgl/SkMask.cpp @@ -15,41 +15,29 @@ ** limitations under the License. */ -#include <limits> - +#include "Sk64.h" #include "SkMask.h" -size_t SkMask::computeImageSize() const -{ - // Prevent too large a number. There is a better fix for this in Skia - // trunk where it returns failure. - long long size = (long long)fBounds.height() * (long long)fRowBytes; - if (size >= std::numeric_limits<size_t>::max() / 2) { -#ifdef WIN32 - __debugbreak(); -#else - abort(); -#endif +/** returns the product if it is positive and fits in 31 bits. Otherwise this + returns 0. + */ +static int32_t safeMul32(int32_t a, int32_t b) { + Sk64 size; + size.setMul(a, b); + if (size.is32() && size.isPos()) { + return size.get32(); } + return 0; +} - return size; +size_t SkMask::computeImageSize() const { + return safeMul32(fBounds.height(), fRowBytes); } -size_t SkMask::computeTotalImageSize() const -{ +size_t SkMask::computeTotalImageSize() const { size_t size = this->computeImageSize(); - if (fFormat == SkMask::k3D_Format) { - // See computeImageSize for why we want to stop here. - if (size > std::numeric_limits<size_t>::max() / 3) { -#ifdef WIN32 - __debugbreak(); -#else - abort(); -#endif - } - - size *= 3; + size = safeMul32(size, 3); } return size; } diff --git a/skia/sgl/SkXfermode.cpp b/skia/sgl/SkXfermode.cpp index e8a202d..1b2479f 100644 --- a/skia/sgl/SkXfermode.cpp +++ b/skia/sgl/SkXfermode.cpp @@ -43,6 +43,16 @@ static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { return result; } +static unsigned saturated_add(unsigned a, unsigned b) { + SkASSERT(a <= 255); + SkASSERT(b <= 255); + unsigned sum = a + b; + if (sum > 255) { + sum = 255; + } + return sum; +} + /////////////////////////////////////////////////////////////////////////////// bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) { @@ -495,6 +505,14 @@ static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { return SkPackARGB32(a, r, g, b); } +static SkPMColor add_modeproc(SkPMColor src, SkPMColor dst) { + unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); + unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); + unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); + unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); + return SkPackARGB32(a, r, g, b); +} + /////////////////////////////////////////////////////////////////////////////// class SkClearXfermode : public SkProcCoeffXfermode { @@ -696,6 +714,8 @@ struct ProcCoeff { SkXfermode::Coeff fDC; }; +#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) + static const ProcCoeff gProcCoeffs[] = { { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, @@ -709,12 +729,11 @@ static const ProcCoeff gProcCoeffs[] = { { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, - // these two can't be represented as coefficients - { darken_modeproc, SkXfermode::Coeff(-1), SkXfermode::Coeff(-1) }, - { lighten_modeproc, SkXfermode::Coeff(-1), SkXfermode::Coeff(-1) }, - // these can use coefficients + { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, + { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, { mult_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, - { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff } + { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, + { add_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF } }; SkXfermode* SkPorterDuff::CreateXfermode(SkPorterDuff::Mode mode) { |