aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapDevice.cpp94
-rw-r--r--src/core/SkCanvas.cpp72
-rw-r--r--src/core/SkDevice.cpp52
-rw-r--r--src/core/SkDeviceImageFilterProxy.h3
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);