diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmap.cpp | 289 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 2 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrPathRenderer.h | 10 | ||||
-rw-r--r-- | src/image/SkImagePriv.cpp | 38 | ||||
-rw-r--r-- | src/image/SkImagePriv.h | 2 | ||||
-rw-r--r-- | src/images/SkDecodingImageGenerator.cpp | 5 |
8 files changed, 208 insertions, 150 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 96d683c0e2..6a70c1e089 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -24,11 +24,6 @@ #include "SkPackBits.h" #include <new> -static bool reset_return_false(SkBitmap* bm) { - bm->reset(); - return false; -} - struct MipLevel { void* fPixels; uint32_t fRowBytes; @@ -130,9 +125,13 @@ void SkBitmap::swap(SkBitmap& other) { SkTSwap(fPixelLockCount, other.fPixelLockCount); SkTSwap(fMipMap, other.fMipMap); SkTSwap(fPixels, other.fPixels); - SkTSwap(fInfo, other.fInfo); SkTSwap(fRowBytes, other.fRowBytes); + SkTSwap(fWidth, other.fWidth); + SkTSwap(fHeight, other.fHeight); + SkTSwap(fConfig, other.fConfig); + SkTSwap(fAlphaType, other.fAlphaType); SkTSwap(fFlags, other.fFlags); + SkTSwap(fBytesPerPixel, other.fBytesPerPixel); SkDEBUGCODE(this->validate();) } @@ -142,10 +141,6 @@ void SkBitmap::reset() { sk_bzero(this, sizeof(*this)); } -SkBitmap::Config SkBitmap::config() const { - return SkColorTypeToBitmapConfig(fInfo.colorType()); -} - int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { int bpp; switch (config) { @@ -172,12 +167,39 @@ int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { } size_t SkBitmap::ComputeRowBytes(Config c, int width) { - return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width); + if (width < 0) { + return 0; + } + + int64_t rowBytes = 0; + + switch (c) { + case kNo_Config: + break; + case kA8_Config: + case kIndex8_Config: + rowBytes = width; + break; + case kRGB_565_Config: + case kARGB_4444_Config: + // assign and then shift, so we don't overflow int + rowBytes = width; + rowBytes <<= 1; + break; + case kARGB_8888_Config: + // assign and then shift, so we don't overflow int + rowBytes = width; + rowBytes <<= 2; + break; + default: + SkDEBUGFAIL("unknown config"); + break; + } + return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0; } int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { - SkColorType ct = SkBitmapConfigToColorType(config); - int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width); + int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width); return rowBytes * height; } @@ -190,10 +212,13 @@ int64_t SkBitmap::ComputeSafeSize64(Config config, uint32_t width, uint32_t height, size_t rowBytes) { - SkImageInfo info = SkImageInfo::Make(width, height, - SkBitmapConfigToColorType(config), - kPremul_SkAlphaType); - return info.getSafeSize64(rowBytes); + int64_t safeSize = 0; + if (height > 0) { + int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width); + safeSize = sk_64_mul(height - 1, rowBytes) + lastRow; + } + SkASSERT(safeSize >= 0); + return safeSize; } size_t SkBitmap::ComputeSafeSize(Config config, @@ -212,36 +237,35 @@ size_t SkBitmap::ComputeSafeSize(Config config, void SkBitmap::getBounds(SkRect* bounds) const { SkASSERT(bounds); bounds->set(0, 0, - SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight)); + SkIntToScalar(fWidth), SkIntToScalar(fHeight)); } void SkBitmap::getBounds(SkIRect* bounds) const { SkASSERT(bounds); - bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight); + bounds->set(0, 0, fWidth, fHeight); } /////////////////////////////////////////////////////////////////////////////// -static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType, +static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, SkAlphaType* canonical = NULL) { - switch (colorType) { - case kUnknown_SkColorType: + switch (config) { + case SkBitmap::kNo_Config: alphaType = kIgnore_SkAlphaType; break; - case kAlpha_8_SkColorType: + case SkBitmap::kA8_Config: if (kUnpremul_SkAlphaType == alphaType) { alphaType = kPremul_SkAlphaType; } // fall-through - case kIndex_8_SkColorType: - case kARGB_4444_SkColorType: - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: + case SkBitmap::kIndex8_Config: + case SkBitmap::kARGB_4444_Config: + case SkBitmap::kARGB_8888_Config: if (kIgnore_SkAlphaType == alphaType) { return false; } break; - case kRGB_565_SkColorType: + case SkBitmap::kRGB_565_Config: alphaType = kOpaque_SkAlphaType; break; default: @@ -253,48 +277,52 @@ static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType, return true; } -bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { - // require that rowBytes fit in 31bits - int64_t mrb = info.minRowBytes64(); - if ((int32_t)mrb != mrb) { - return reset_return_false(this); - } - if ((int64_t)rowBytes != (int32_t)rowBytes) { - return reset_return_false(this); +bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, + SkAlphaType alphaType) { + if ((width | height) < 0) { + goto BAD_CONFIG; } - - if (info.width() < 0 || info.height() < 0) { - return reset_return_false(this); + if (rowBytes == 0) { + rowBytes = SkBitmap::ComputeRowBytes(config, width); + if (0 == rowBytes && kNo_Config != config && width > 0) { + goto BAD_CONFIG; + } } - if (kUnknown_SkColorType == info.colorType()) { - rowBytes = 0; - } else if (0 == rowBytes) { - rowBytes = (size_t)mrb; - } else if (rowBytes < info.minRowBytes()) { - return reset_return_false(this); + if (!validate_alphaType(config, alphaType, &alphaType)) { + goto BAD_CONFIG; } this->freePixels(); - fInfo = info; - fRowBytes = SkToU32(rowBytes); + fConfig = SkToU8(config); + fAlphaType = SkToU8(alphaType); + fWidth = width; + fHeight = height; + fRowBytes = SkToU32(rowBytes); + + fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config); + + SkDEBUGCODE(this->validate();) return true; + + // if we got here, we had an error, so we reset the bitmap to empty +BAD_CONFIG: + this->reset(); + return false; } -bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, - SkAlphaType alphaType) { - SkColorType ct = SkBitmapConfigToColorType(config); - return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType), - rowBytes); +bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { + return this->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth, + info.fHeight, rowBytes, info.fAlphaType); } bool SkBitmap::setAlphaType(SkAlphaType alphaType) { - if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) { + if (!validate_alphaType(this->config(), alphaType, &alphaType)) { return false; } - if (fInfo.fAlphaType != alphaType) { - fInfo.fAlphaType = alphaType; + if (fAlphaType != alphaType) { + fAlphaType = SkToU8(alphaType); if (fPixelRef) { fPixelRef->changeAlphaType(alphaType); } @@ -311,7 +339,7 @@ void SkBitmap::updatePixelsFromRef() const { if (NULL != p) { p = (char*)p + fPixelRefOrigin.fY * fRowBytes - + fPixelRefOrigin.fX * fInfo.bytesPerPixel(); + + fPixelRefOrigin.fX * fBytesPerPixel; } fPixels = p; fColorTable = fPixelRef->colorTable(); @@ -351,6 +379,20 @@ static bool config_to_colorType(SkBitmap::Config config, SkColorType* ctOut) { return true; } +bool SkBitmap::asImageInfo(SkImageInfo* info) const { + SkColorType ct; + if (!config_to_colorType(this->config(), &ct)) { + return false; + } + if (info) { + info->fWidth = fWidth; + info->fHeight = fHeight; + info->fAlphaType = this->alphaType(); + info->fColorType = ct; + } + return true; +} + SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { #ifdef SK_DEBUG if (pr) { @@ -362,7 +404,7 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { SkASSERT(info.fColorType == prInfo.fColorType); switch (prInfo.fAlphaType) { case kIgnore_SkAlphaType: - SkASSERT(fInfo.fAlphaType == kIgnore_SkAlphaType); + SkASSERT(fAlphaType == kIgnore_SkAlphaType); break; case kOpaque_SkAlphaType: case kPremul_SkAlphaType: @@ -460,6 +502,11 @@ bool SkBitmap::allocPixels(Allocator* allocator, SkColorTable* ctable) { /////////////////////////////////////////////////////////////////////////////// +static bool reset_return_false(SkBitmap* bm) { + bm->reset(); + return false; +} + bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) { if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { @@ -515,6 +562,10 @@ bool SkBitmap::allocConfigPixels(Config config, int width, int height, } SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; + if (!validate_alphaType(config, at, &at)) { + return false; + } + return this->allocPixels(SkImageInfo::Make(width, height, ct, at)); } @@ -586,6 +637,13 @@ bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, /////////////////////////////////////////////////////////////////////////////// +size_t SkBitmap::getSafeSize() const { + // This is intended to be a size_t version of ComputeSafeSize64(), just + // faster. The computation is meant to be identical. + return (fHeight ? ((fHeight - 1) * fRowBytes) + + ComputeRowBytes(this->config(), fWidth): 0); +} + bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, size_t dstRowBytes, bool preserveDstPad) const { @@ -593,10 +651,9 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, dstRowBytes = fRowBytes; } - if (dstRowBytes < fInfo.minRowBytes() || - dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) { + if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) || + dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) return false; - } if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { size_t safeSize = this->getSafeSize(); @@ -613,15 +670,16 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, } } else { // If destination has different stride than us, then copy line by line. - if (fInfo.getSafeSize(dstRowBytes) > dstSize) { + if (ComputeSafeSize(this->config(), fWidth, fHeight, dstRowBytes) > + dstSize) return false; - } else { + else { // Just copy what we need on each line. - size_t rowBytes = fInfo.minRowBytes(); + size_t rowBytes = ComputeRowBytes(this->config(), fWidth); SkAutoLockPixels lock(*this); const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); - for (int row = 0; row < fInfo.fHeight; + for (uint32_t row = 0; row < fHeight; row++, srcP += fRowBytes, dstP += dstRowBytes) { memcpy(dstP, srcP, rowBytes); } @@ -665,19 +723,19 @@ void* SkBitmap::getAddr(int x, int y) const { char* base = (char*)this->getPixels(); if (base) { base += y * this->rowBytes(); - switch (this->colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: + switch (this->config()) { + case SkBitmap::kARGB_8888_Config: base += x << 2; break; - case kARGB_4444_SkColorType: - case kRGB_565_SkColorType: + case SkBitmap::kARGB_4444_Config: + case SkBitmap::kRGB_565_Config: base += x << 1; break; - case kAlpha_8_SkColorType: - case kIndex_8_SkColorType: + case SkBitmap::kA8_Config: + case SkBitmap::kIndex8_Config: base += x; break; + break; default: SkDEBUGFAIL("Can't return addr for config"); base = NULL; @@ -815,12 +873,8 @@ void SkBitmap::internalErase(const SkIRect& area, } #endif - switch (fInfo.colorType()) { - case kUnknown_SkColorType: - case kIndex_8_SkColorType: - return; // can't erase - default: - break; + if (kNo_Config == fConfig || kIndex8_Config == fConfig) { + return; } SkAutoLockPixels alp(*this); @@ -840,8 +894,8 @@ void SkBitmap::internalErase(const SkIRect& area, b = SkAlphaMul(b, a); } - switch (this->colorType()) { - case kAlpha_8_SkColorType: { + switch (fConfig) { + case kA8_Config: { uint8_t* p = this->getAddr8(area.fLeft, area.fTop); while (--height >= 0) { memset(p, a, width); @@ -849,12 +903,12 @@ void SkBitmap::internalErase(const SkIRect& area, } break; } - case kARGB_4444_SkColorType: - case kRGB_565_SkColorType: { + case kARGB_4444_Config: + case kRGB_565_Config: { uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; uint16_t v; - if (kARGB_4444_SkColorType == this->colorType()) { + if (kARGB_4444_Config == fConfig) { v = pack_8888_to_4444(a, r, g, b); } else { v = SkPackRGB16(r >> (8 - SK_R16_BITS), @@ -867,9 +921,7 @@ void SkBitmap::internalErase(const SkIRect& area, } break; } - case kPMColor_SkColorType: { - // what to do about BGRA or RGBA (which ever is != PMColor ? - // for now we don't support them. + case kARGB_8888_Config: { uint32_t* p = this->getAddr32(area.fLeft, area.fTop); uint32_t v = SkPackARGB32(a, r, g, b); @@ -879,8 +931,6 @@ void SkBitmap::internalErase(const SkIRect& area, } break; } - default: - return; // no change, so don't call notifyPixelsChanged() } this->notifyPixelsChanged(); @@ -996,8 +1046,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { if (fPixelRef) { SkIRect subset; - subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, - fInfo.width(), fInfo.height()); + subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); if (fPixelRef->readPixels(&tmpSrc, &subset)) { SkASSERT(tmpSrc.width() == this->width()); SkASSERT(tmpSrc.height() == this->height()); @@ -1111,8 +1160,6 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { } bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { - const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); - if (!this->canCopyTo(dstConfig)) { return false; } @@ -1123,7 +1170,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); if (pixelRef) { uint32_t rowBytes; - if (this->colorType() == dstCT) { + if (dstConfig == fConfig) { // Since there is no subset to pass to deepCopy, and deepCopy // succeeded, the new pixel ref must be identical. SkASSERT(fPixelRef->info() == pixelRef->info()); @@ -1134,12 +1181,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { // With the new config, an appropriate fRowBytes will be computed by setConfig. rowBytes = 0; } - - SkImageInfo info = fInfo; - info.fColorType = dstCT; - if (!dst->setConfig(info, rowBytes)) { - return false; - } + dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); return true; } @@ -1542,8 +1584,11 @@ enum { }; void SkBitmap::flatten(SkWriteBuffer& buffer) const { - fInfo.flatten(buffer); + buffer.writeInt(fWidth); + buffer.writeInt(fHeight); buffer.writeInt(fRowBytes); + buffer.writeInt(fConfig); + buffer.writeInt(fAlphaType); if (fPixelRef) { if (fPixelRef->getFactory()) { @@ -1563,17 +1608,19 @@ void SkBitmap::flatten(SkWriteBuffer& buffer) const { void SkBitmap::unflatten(SkReadBuffer& buffer) { this->reset(); - SkImageInfo info; - info.unflatten(buffer); - size_t rowBytes = buffer.readInt(); - buffer.validate((info.width() >= 0) && (info.height() >= 0) && - SkColorTypeIsValid(info.fColorType) && - SkAlphaTypeIsValid(info.fAlphaType) && - validate_alphaType(info.fColorType, info.fAlphaType) && - info.validRowBytes(rowBytes)); + int width = buffer.readInt(); + int height = buffer.readInt(); + int rowBytes = buffer.readInt(); + Config config = (Config)buffer.readInt(); + SkAlphaType alphaType = (SkAlphaType)buffer.readInt(); + buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) && + SkIsValidConfig(config) && validate_alphaType(config, alphaType)); - bool configIsValid = this->setConfig(info, rowBytes); - buffer.validate(configIsValid); + bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaType); + // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following test can create false + // positives if the multiplication causes an integer overflow. Use the division instead. + buffer.validate(configIsValid && (fBytesPerPixel > 0) && + ((fRowBytes / fBytesPerPixel) >= fWidth)); int reftype = buffer.readInt(); if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || @@ -1583,7 +1630,7 @@ void SkBitmap::unflatten(SkReadBuffer& buffer) { SkIPoint origin; origin.fX = buffer.readInt(); origin.fY = buffer.readInt(); - size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPerPixel(); + size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixel; SkPixelRef* pr = buffer.readPixelRef(); if (!buffer.validate((NULL == pr) || (pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) { @@ -1616,14 +1663,15 @@ SkBitmap::RLEPixels::~RLEPixels() { #ifdef SK_DEBUG void SkBitmap::validate() const { - fInfo.validate(); - SkASSERT(fInfo.validRowBytes(fRowBytes)); + SkASSERT(fConfig < kConfigCount); + SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth)); uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImmutable_Flag; #ifdef SK_BUILD_FOR_ANDROID allFlags |= kHasHardwareMipMap_Flag; #endif SkASSERT(fFlags <= allFlags); SkASSERT(fPixelLockCount >= 0); + SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel); if (fPixels) { SkASSERT(fPixelRef); @@ -1632,9 +1680,9 @@ void SkBitmap::validate() const { SkASSERT(fPixelRef->rowBytes() == fRowBytes); SkASSERT(fPixelRefOrigin.fX >= 0); SkASSERT(fPixelRefOrigin.fY >= 0); - SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrigin.fX); - SkASSERT(fPixelRef->info().fHeight >= (int)this->height() + fPixelRefOrigin.fY); - SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes()); + SkASSERT(fPixelRef->info().fWidth >= (int)fWidth + fPixelRefOrigin.fX); + SkASSERT(fPixelRef->info().fHeight >= (int)fHeight + fPixelRefOrigin.fY); + SkASSERT(fPixelRef->rowBytes() >= fWidth * fBytesPerPixel); } else { SkASSERT(NULL == fColorTable); } @@ -1680,14 +1728,3 @@ void SkBitmap::toString(SkString* str) const { str->append(")"); } #endif - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_DEBUG -void SkImageInfo::validate() const { - SkASSERT(fWidth >= 0); - SkASSERT(fHeight >= 0); - SkASSERT(SkColorTypeIsValid(fColorType)); - SkASSERT(SkAlphaTypeIsValid(fAlphaType)); -} -#endif diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 0a36811f4d..35e0818dd0 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -70,7 +70,7 @@ static bool path_needs_SW_renderer(GrContext* context, SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.getFillType()); // the 'false' parameter disallows use of the SW path renderer - GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu, + GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu, false, type, fillType)); return NULL == acp.renderer(); } @@ -310,7 +310,7 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) { //////////////////////////////////////////////////////////////////////////////// bool GrClipMaskManager::drawFilledPath(GrTexture* target, - GrPathRenderer* pathRenderer, + GrPathRenderer* pathRenderer, bool isAA) { GrDrawState* drawState = fGpu->drawState(); @@ -349,7 +349,7 @@ bool GrClipMaskManager::drawElement(GrTexture* target, GrPathRendererChain::kColor_DrawType; SkPath::FillType fillType = element->getPath().getFillType(); GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRenderer( - element->getPath(), + element->getPath(), stroke, fGpu, false, type, SkPath::ConvertToNonInverseFillType(fillType))); if (NULL == acp.renderer()) { @@ -381,9 +381,9 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : GrPathRendererChain::kStencilAndColor_DrawType; SkPath::FillType fillType = element->getPath().getFillType(); - acp->set(this->getContext()->getPathRenderer(element->getPath(), + acp->set(this->getContext()->getPathRenderer(element->getPath(), stroke, fGpu, false, type, - SkPath::ConvertToNonInverseFillType(fillType))); + SkPath::ConvertToNonInverseFillType(fillType))); return NULL != acp->renderer(); } default: diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index 5e7d737868..fa54f3ce0e 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -141,7 +141,7 @@ private: // Determines whether it is possible to draw the element to both the stencil buffer and the // alpha mask simultaneously. If so and the element is a path a compatible path renderer is // also returned. - bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, + bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer::AutoClearPath* pr); void mergeMask(GrTexture* dstMask, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 3fbdf16005..ab20dc3902 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1155,7 +1155,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); // Try a 1st time without stroking the path and without allowing the SW renderer - GrPathRenderer::AutoClearPath acp(this->getPathRenderer(*pathPtr, *stroke, + GrPathRenderer::AutoClearPath acp(this->getPathRenderer(*pathPtr, *stroke, target, false, type, pathPtr->getFillType())); diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index 4dafcff0e1..692cefc7f1 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -100,8 +100,8 @@ public: } /** - * Returns true if this path renderer is able to render the current path. Returning false - * allows the caller to fallback to another path renderer This function is called when + * Returns true if this path renderer is able to render the current path. Returning false + * allows the caller to fallback to another path renderer This function is called when * searching for a path renderer capable of rendering a path. * * @param stroke The stroke information (width, join, cap) @@ -114,8 +114,8 @@ public: const GrDrawTarget* target, bool antiAlias) const = 0; /** - * Draws the current path into the draw target. If getStencilSupport() would return - * kNoRestriction then the subclass must respect the stencil settings of the + * Draws the current path into the draw target. If getStencilSupport() would return + * kNoRestriction then the subclass must respect the stencil settings of the * target's draw state. * * @param stroke the stroke information (width, join, cap) @@ -134,7 +134,7 @@ public: /** * Draws the current path to the stencil buffer. Assume the writable stencil bits are already - * initialized to zero. The pixels inside the path will have non-zero stencil values + * initialized to zero. The pixels inside the path will have non-zero stencil values * afterwards. * * @param stroke the stroke information (width, join, cap) diff --git a/src/image/SkImagePriv.cpp b/src/image/SkImagePriv.cpp index a044aad0a0..43cc44b2fa 100644 --- a/src/image/SkImagePriv.cpp +++ b/src/image/SkImagePriv.cpp @@ -37,19 +37,35 @@ SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo& info) { return SkColorTypeToBitmapConfig(info.fColorType); } -SkColorType SkBitmapConfigToColorType(SkBitmap::Config config) { - static const SkColorType gCT[] = { - kUnknown_SkColorType, // kNo_Config - kAlpha_8_SkColorType, // kA8_Config - kIndex_8_SkColorType, // kIndex8_Config - kRGB_565_SkColorType, // kRGB_565_Config - kARGB_4444_SkColorType, // kARGB_4444_Config - kPMColor_SkColorType, // kARGB_8888_Config - }; - SkASSERT((unsigned)config < SK_ARRAY_COUNT(gCT)); - return gCT[config]; +bool SkBitmapConfigToColorType(SkBitmap::Config config, SkColorType* ctOut) { + SkColorType ct; + switch (config) { + case SkBitmap::kA8_Config: + ct = kAlpha_8_SkColorType; + break; + case SkBitmap::kIndex8_Config: + ct = kIndex_8_SkColorType; + break; + case SkBitmap::kRGB_565_Config: + ct = kRGB_565_SkColorType; + break; + case SkBitmap::kARGB_4444_Config: + ct = kARGB_4444_SkColorType; + break; + case SkBitmap::kARGB_8888_Config: + ct = kPMColor_SkColorType; + break; + case SkBitmap::kNo_Config: + default: + return false; + } + if (ctOut) { + *ctOut = ct; + } + return true; } + SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { SkImageInfo info; if (!bm.asImageInfo(&info)) { diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h index 8883e2c070..7c19c734c2 100644 --- a/src/image/SkImagePriv.h +++ b/src/image/SkImagePriv.h @@ -15,7 +15,7 @@ class SkPicture; extern SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo&); extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType); -extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config); +extern bool SkBitmapConfigToColorType(SkBitmap::Config, SkColorType* ctOut); // Call this if you explicitly want to use/share this pixelRef in the image extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*, diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp index 1e28136603..153d1e220b 100644 --- a/src/images/SkDecodingImageGenerator.cpp +++ b/src/images/SkDecodingImageGenerator.cpp @@ -275,6 +275,11 @@ SkImageGenerator* SkDecodingImageGenerator::Create( info.fHeight = bitmap.height(); info.fColorType = opts.fRequestedColorType; info.fAlphaType = bitmap.alphaType(); + + // Sanity check. + SkDEBUGCODE(SkColorType tmp;) + SkASSERT(SkBitmapConfigToColorType(config, &tmp)); + SkASSERT(tmp == opts.fRequestedColorType); } return SkNEW_ARGS(SkDecodingImageGenerator, (data, autoStream.detach(), info, |