add SkBitmap::installPixelRef()
BUG=
R=scroggo@google.com
Review URL: https://codereview.chromium.org/129423002
git-svn-id: http://skia.googlecode.com/svn/trunk@13055 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index b8117bd..1cb4fd7 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -268,6 +268,16 @@
*/
void setPixels(void* p, SkColorTable* ctable = NULL);
+ /**
+ * Install the specified pixelref into the bitmap, with an optional rect
+ * for referencing a subset of the pixels in the pixelref. This sets the
+ * config/width/height/alphatype of the bitmap to match the pixelref.
+ *
+ * The subset rect, if not null, is intersected with the bounds of the
+ * pixelref (taken from its SkImageInfo).
+ */
+ SkPixelRef* installPixelRef(SkPixelRef*, const SkIRect* subset = NULL);
+
/** Copies the bitmap's pixels to the location pointed at by dst and returns
true if possible, returns false otherwise.
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index 1165479..e0bce2a 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -109,6 +109,60 @@
SkColorType fColorType;
SkAlphaType fAlphaType;
+ static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) {
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ SkImageInfo info = {
+ width, height, ct, at
+ };
+ return info;
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type.
+ */
+ static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ SkImageInfo info = {
+ width, height, kPMColor_SkColorType, at
+ };
+ return info;
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type, and the alphatype to premul.
+ */
+ static SkImageInfo MakeN32Premul(int width, int height) {
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ SkImageInfo info = {
+ width, height, kPMColor_SkColorType, kPremul_SkAlphaType
+ };
+ return info;
+ }
+
+ /**
+ * Sets colortype to the native ARGB32 type, and the alphatype to opaque.
+ */
+ static SkImageInfo MakeN32Opaque(int width, int height) {
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ SkImageInfo info = {
+ width, height, kPMColor_SkColorType, kOpaque_SkAlphaType
+ };
+ return info;
+ }
+
+ static SkImageInfo MakeA8(int width, int height) {
+ SkASSERT(width >= 0);
+ SkASSERT(height >= 0);
+ SkImageInfo info = {
+ width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType
+ };
+ return info;
+ }
+
bool isOpaque() const {
return SkAlphaTypeIsOpaque(fAlphaType);
}
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index f950e28..6615b1c 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -333,6 +333,30 @@
return true;
}
+SkPixelRef* SkBitmap::installPixelRef(SkPixelRef* pr, const SkIRect* subset) {
+ if (NULL == pr) {
+ this->reset();
+ return NULL;
+ }
+
+ const SkImageInfo& info = pr->info();
+
+ fConfig = SkColorTypeToBitmapConfig(info.fColorType);
+ fAlphaType = info.fAlphaType;
+ fBytesPerPixel = info.bytesPerPixel();
+ // not known until we're locked
+ fRowBytes = 0;
+
+ SkIRect bounds = { 0, 0, info.fWidth, info.fHeight };
+ if (subset && !bounds.intersect(*subset)) {
+ bounds.setEmpty();
+ }
+
+ fWidth = bounds.width();
+ fHeight = bounds.height();
+ return this->setPixelRef(pr, bounds.left(), bounds.top());
+}
+
void SkBitmap::updatePixelsFromRef() const {
if (NULL != fPixelRef) {
if (fPixelLockCount > 0) {
diff --git a/src/core/SkImageFilterUtils.cpp b/src/core/SkImageFilterUtils.cpp
index 92fe67e..076ef9b 100644
--- a/src/core/SkImageFilterUtils.cpp
+++ b/src/core/SkImageFilterUtils.cpp
@@ -15,14 +15,8 @@
#include "SkGr.h"
bool SkImageFilterUtils::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) {
- SkImageInfo info = {
- width,
- height,
- kPMColor_SkColorType,
- kPremul_SkAlphaType,
- };
- result->setConfig(info);
- result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+ SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+ result->installPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
return true;
}
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index fc3148b..68663f0 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -293,14 +293,10 @@
return false;
}
- SkImageInfo info = {
- bitmap->width(),
- bitmap->height(),
- kPMColor_SkColorType,
- bitmap->alphaType()
- };
+ SkImageInfo info = SkImageInfo::MakeN32(bitmap->width(), bitmap->height(),
+ bitmap->alphaType());
- bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef,
+ bitmap->installPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef,
(info, dm, bitmap->rowBytes())))->unref();
bitmap->lockPixels();
return bitmap->readyToDraw();
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 6925ad2..8ed40a7 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -583,8 +583,7 @@
if (fMapper) {
// force our cahce32pixelref to be built
(void)this->getCache32();
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
- bitmap->setPixelRef(fCache32PixelRef);
+ bitmap->installPixelRef(fCache32PixelRef);
return;
}
@@ -624,8 +623,7 @@
if (!gCache->find(storage.get(), size, bitmap)) {
// force our cahce32pixelref to be built
(void)this->getCache32();
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
- bitmap->setPixelRef(fCache32PixelRef);
+ bitmap->installPixelRef(fCache32PixelRef);
gCache->add(storage.get(), size, *bitmap);
}
diff --git a/src/image/SkImagePriv.cpp b/src/image/SkImagePriv.cpp
index 43cc44b..af15a75 100644
--- a/src/image/SkImagePriv.cpp
+++ b/src/image/SkImagePriv.cpp
@@ -74,7 +74,7 @@
SkImage* image = NULL;
if (canSharePixelRef || bm.isImmutable()) {
- image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
+ image = SkNewImageFromPixelRef(bm.pixelRef());
} else {
bm.lockPixels();
if (bm.getPixels()) {
diff --git a/src/image/SkImagePriv.h b/src/image/SkImagePriv.h
index 7c19c73..2812a8f 100644
--- a/src/image/SkImagePriv.h
+++ b/src/image/SkImagePriv.h
@@ -18,8 +18,7 @@
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*,
- size_t rowBytes);
+extern SkImage* SkNewImageFromPixelRef(SkPixelRef*);
/**
* Examines the bitmap to decide if it can share the existing pixelRef, or
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 7bd1f7e..5574f45 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -13,6 +13,7 @@
class SkImage_Base : public SkImage {
public:
SkImage_Base(int width, int height) : INHERITED(width, height) {}
+ SkImage_Base(const SkImageInfo& info) : INHERITED(info.fWidth, info.fHeight) {}
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) = 0;
virtual void onDrawRectToRect(SkCanvas*, const SkRect* src,
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 32d53fc..b80fbb3 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -58,7 +58,7 @@
virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
// exposed for SkSurface_Raster via SkNewImageFromPixelRef
- SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
+ SkImage_Raster(SkPixelRef*);
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
@@ -84,18 +84,16 @@
SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
: INHERITED(info.fWidth, info.fHeight) {
- fBitmap.setConfig(info, rowBytes);
SkAutoTUnref<SkPixelRef> ref(
SkMallocPixelRef::NewWithData(info, rowBytes, NULL, data, 0));
- fBitmap.setPixelRef(ref);
+ fBitmap.installPixelRef(ref);
fBitmap.setImmutable();
}
-SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
- : INHERITED(info.fWidth, info.fHeight)
+SkImage_Raster::SkImage_Raster(SkPixelRef* pr)
+ : INHERITED(pr->info())
{
- fBitmap.setConfig(info, rowBytes);
- fBitmap.setPixelRef(pr);
+ fBitmap.installPixelRef(pr);
}
SkImage_Raster::~SkImage_Raster() {}
@@ -155,9 +153,8 @@
return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
}
-SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
- size_t rowBytes) {
- return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
+SkImage* SkNewImageFromPixelRef(SkPixelRef* pr) {
+ return SkNEW_ARGS(SkImage_Raster, (pr));
}
SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 1b218eb..7010b5f 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -85,15 +85,12 @@
}
SkSurface_Raster::SkSurface_Raster(SkPixelRef* pr)
- : INHERITED(pr->info().fWidth, pr->info().fHeight)
+ : INHERITED(pr->info())
{
- const SkImageInfo& info = pr->info();
-
- fBitmap.setConfig(info, info.minRowBytes());
- fBitmap.setPixelRef(pr);
+ fBitmap.installPixelRef(pr);
fWeOwnThePixels = true;
- if (!info.isOpaque()) {
+ if (!pr->info().isOpaque()) {
fBitmap.eraseColor(SK_ColorTRANSPARENT);
}
}
diff --git a/src/lazy/SkCachingPixelRef.cpp b/src/lazy/SkCachingPixelRef.cpp
index f1510fb..f5026c7 100644
--- a/src/lazy/SkCachingPixelRef.cpp
+++ b/src/lazy/SkCachingPixelRef.cpp
@@ -12,15 +12,13 @@
SkBitmap* dst) {
SkImageInfo info;
SkASSERT(dst != NULL);
- if ((NULL == generator)
- || !(generator->getInfo(&info))
- || !dst->setConfig(info, 0)) {
+ if (!generator || !generator->getInfo(&info)) {
SkDELETE(generator);
return false;
}
SkAutoTUnref<SkCachingPixelRef> ref(SkNEW_ARGS(SkCachingPixelRef,
(info, generator, dst->rowBytes())));
- dst->setPixelRef(ref);
+ dst->installPixelRef(ref);
return true;
}
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
index abd80f2..eb5c2f9 100644
--- a/src/lazy/SkDiscardablePixelRef.cpp
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -94,6 +94,6 @@
SkAutoTUnref<SkDiscardablePixelRef> ref(
SkNEW_ARGS(SkDiscardablePixelRef,
(info, autoGenerator.detach(), dst->rowBytes(), factory)));
- dst->setPixelRef(ref);
+ dst->installPixelRef(ref);
return true;
}
diff --git a/tests/MallocPixelRefTest.cpp b/tests/MallocPixelRefTest.cpp
index e169763..62d1e9d 100644
--- a/tests/MallocPixelRefTest.cpp
+++ b/tests/MallocPixelRefTest.cpp
@@ -23,7 +23,7 @@
*/
DEF_TEST(MallocPixelRef, reporter) {
REPORTER_ASSERT(reporter, true);
- SkImageInfo info = {10, 13, kPMColor_SkColorType, kPremul_SkAlphaType};
+ SkImageInfo info = SkImageInfo::MakePMPremul(10, 13);
{
SkAutoTUnref<SkMallocPixelRef> pr(
SkMallocPixelRef::NewAllocate(info, info.minRowBytes() - 1, NULL));
diff --git a/tests/PixelRefTest.cpp b/tests/PixelRefTest.cpp
index e0ffd7a..3486898 100644
--- a/tests/PixelRefTest.cpp
+++ b/tests/PixelRefTest.cpp
@@ -51,7 +51,7 @@
} // namespace
DEF_TEST(PixelRef_GenIDChange, r) {
- SkImageInfo info = { 10, 10, kPMColor_SkColorType, kPremul_SkAlphaType };
+ SkImageInfo info = SkImageInfo::MakePMPremul(10, 10);
SkAutoTUnref<SkPixelRef> pixelRef(SkMallocPixelRef::NewAllocate(info, 0, NULL));