diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmapDevice.cpp | 94 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 72 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 52 | ||||
-rw-r--r-- | src/core/SkDeviceImageFilterProxy.h | 3 |
4 files changed, 130 insertions, 91 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index 374bef98c1..0eff33cf7e 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -15,16 +15,60 @@ #define CHECK_FOR_ANNOTATION(paint) \ do { if (paint.getAnnotation()) { return; } } while (0) -SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) - : fBitmap(bitmap) { - SkASSERT(SkBitmap::kARGB_4444_Config != bitmap.config()); +static bool valid_for_bitmap_device(const SkImageInfo& info, + SkAlphaType* newAlphaType) { + if (info.width() < 0 || info.height() < 0) { + return false; + } + + // TODO: can we stop supporting kUnknown in SkBitmkapDevice? + if (kUnknown_SkColorType == info.colorType()) { + if (newAlphaType) { + *newAlphaType = kIgnore_SkAlphaType; + } + return true; + } + + switch (info.alphaType()) { + case kPremul_SkAlphaType: + case kOpaque_SkAlphaType: + break; + default: + return false; + } + + SkAlphaType canonicalAlphaType = info.alphaType(); + + switch (info.colorType()) { + case kAlpha_8_SkColorType: + break; + case kRGB_565_SkColorType: + canonicalAlphaType = kOpaque_SkAlphaType; + break; + case kPMColor_SkColorType: + break; + default: + return false; + } + + if (newAlphaType) { + *newAlphaType = canonicalAlphaType; + } + return true; +} + +SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) : fBitmap(bitmap) { + SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL)); } SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties) : SkBaseDevice(deviceProperties) - , fBitmap(bitmap) { + , fBitmap(bitmap) +{ + SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL)); } +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG void SkBitmapDevice::init(SkBitmap::Config config, int width, int height, bool isOpaque) { fBitmap.setConfig(config, width, height, 0, isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); @@ -50,8 +94,34 @@ SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, b { this->init(config, width, height, isOpaque); } +#endif +SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo, + const SkDeviceProperties* props) { + SkImageInfo info = origInfo; + if (!valid_for_bitmap_device(info, &info.fAlphaType)) { + return NULL; + } + + SkBitmap bitmap; -SkBitmapDevice::~SkBitmapDevice() { + if (kUnknown_SkColorType == info.colorType()) { + if (!bitmap.setConfig(info)) { + return NULL; + } + } else { + if (!bitmap.allocPixels(info)) { + return NULL; + } + if (!bitmap.info().isOpaque()) { + bitmap.eraseColor(SK_ColorTRANSPARENT); + } + } + + if (props) { + return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props)); + } else { + return SkNEW_ARGS(SkBitmapDevice, (bitmap)); + } } SkImageInfo SkBitmapDevice::imageInfo() const { @@ -65,18 +135,8 @@ void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) { fBitmap.lockPixels(); } -SkBaseDevice* SkBitmapDevice::onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) { - SkBitmapDevice* device = SkNEW_ARGS(SkBitmapDevice,(config, width, height, - isOpaque, this->getDeviceProperties())); - // Check if allocation failed and delete device if it did fail - if ((device->width() != width) || (device->height() != height)) { - SkDELETE(device); - device = NULL; - } - return device; +SkBaseDevice* SkBitmapDevice::onCreateDevice(const SkImageInfo& info, Usage usage) { + return SkBitmapDevice::Create(info, &this->getDeviceProperties()); } void SkBitmapDevice::lockPixels() { diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index f5e91ffc43..61acf269b4 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -746,46 +746,6 @@ int SkCanvas::save(SaveFlags flags) { return this->internalSave(flags); } -#define C32MASK (1 << SkBitmap::kARGB_8888_Config) -#define C16MASK (1 << SkBitmap::kRGB_565_Config) -#define C8MASK (1 << SkBitmap::kA8_Config) - -static SkBitmap::Config resolve_config(SkCanvas* canvas, - const SkIRect& bounds, - SkCanvas::SaveFlags flags, - bool* isOpaque) { - *isOpaque = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) == 0; - -#if 0 - // loop through and union all the configs we may draw into - uint32_t configMask = 0; - for (int i = canvas->countLayerDevices() - 1; i >= 0; --i) - { - SkBaseDevice* device = canvas->getLayerDevice(i); - if (device->intersects(bounds)) - configMask |= 1 << device->config(); - } - - // if the caller wants alpha or fullcolor, we can't return 565 - if (flags & (SkCanvas::kFullColorLayer_SaveFlag | - SkCanvas::kHasAlphaLayer_SaveFlag)) - configMask &= ~C16MASK; - - switch (configMask) { - case C8MASK: // if we only have A8, return that - return SkBitmap::kA8_Config; - - case C16MASK: // if we only have 565, return that - return SkBitmap::kRGB_565_Config; - - default: - return SkBitmap::kARGB_8888_Config; // default answer - } -#else - return SkBitmap::kARGB_8888_Config; // default answer -#endif -} - static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; } @@ -840,15 +800,9 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, } static SkBaseDevice* createCompatibleDevice(SkCanvas* canvas, - SkBitmap::Config config, - int width, int height, - bool isOpaque) { + const SkImageInfo& info) { SkBaseDevice* device = canvas->getDevice(); - if (device) { - return device->createCompatibleDevice(config, width, height, isOpaque); - } else { - return NULL; - } + return device ? device->createCompatibleDevice(info) : NULL; } int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, @@ -878,16 +832,15 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, } } - bool isOpaque; - SkBitmap::Config config = resolve_config(this, ir, flags, &isOpaque); + bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); + SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); SkBaseDevice* device; if (paint && paint->getImageFilter()) { - device = createCompatibleDevice(this, config, ir.width(), ir.height(), - isOpaque); + device = createCompatibleDevice(this, info); } else { - device = this->createLayerDevice(config, ir.width(), ir.height(), - isOpaque); + device = this->createLayerDevice(info); } if (NULL == device) { SkDebugf("Unable to create device for layer."); @@ -1607,16 +1560,9 @@ const SkRegion& SkCanvas::getTotalClip() const { return fMCRec->fRasterClip->forceGetBW(); } -SkBaseDevice* SkCanvas::createLayerDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque) { +SkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { SkBaseDevice* device = this->getTopDevice(); - if (device) { - return device->createCompatibleDeviceForSaveLayer(config, width, height, - isOpaque); - } else { - return NULL; - } + return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; } GrContext* SkCanvas::getGrContext() { diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 364b106dd8..d69e4afab2 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -42,19 +42,53 @@ SkBaseDevice::~SkBaseDevice() { delete fMetaData; } +SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) { +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG + // We call the old method to support older subclasses. + // If they have, we return their device, else we use the new impl. + SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); + SkBaseDevice* dev = this->onCreateCompatibleDevice(config, + info.width(), + info.height(), + info.isOpaque(), + kGeneral_Usage); + if (dev) { + return dev; + } + // fall through to new impl +#endif + return this->onCreateDevice(info, kGeneral_Usage); +} + +SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) { +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG + // We call the old method to support older subclasses. + // If they have, we return their device, else we use the new impl. + SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); + SkBaseDevice* dev = this->onCreateCompatibleDevice(config, + info.width(), + info.height(), + info.isOpaque(), + kSaveLayer_Usage); + if (dev) { + return dev; + } + // fall through to new impl +#endif + return this->onCreateDevice(info, kSaveLayer_Usage); +} + +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque) { - return this->onCreateCompatibleDevice(config, width, height, - isOpaque, kGeneral_Usage); -} - -SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config, - int width, int height, - bool isOpaque) { - return this->onCreateCompatibleDevice(config, width, height, - isOpaque, kSaveLayer_Usage); + SkImageInfo info = SkImageInfo::Make(width, height, + SkBitmapConfigToColorType(config), + isOpaque ? kOpaque_SkAlphaType + : kPremul_SkAlphaType); + return this->createCompatibleDevice(info); } +#endif SkMetaData& SkBaseDevice::getMetaData() { // metadata users are rare, so we lazily allocate it. If that changes we diff --git a/src/core/SkDeviceImageFilterProxy.h b/src/core/SkDeviceImageFilterProxy.h index 800e42c1f6..6c968e945e 100644 --- a/src/core/SkDeviceImageFilterProxy.h +++ b/src/core/SkDeviceImageFilterProxy.h @@ -15,8 +15,7 @@ public: SkDeviceImageFilterProxy(SkBaseDevice* device) : fDevice(device) {} virtual SkBaseDevice* createDevice(int w, int h) SK_OVERRIDE { - return fDevice->createCompatibleDevice(SkBitmap::kARGB_8888_Config, - w, h, false); + return fDevice->createCompatibleDevice(SkImageInfo::MakeN32Premul(w, h)); } virtual bool canHandleImageFilter(const SkImageFilter* filter) SK_OVERRIDE { return fDevice->canHandleImageFilter(filter); |