Add image->bitmap
BUG=skia: patch from issue 1212163012 at patchset 1 (http://crrev.com/1212163012#ps1) Review URL: https://codereview.chromium.org/1208993017
This commit is contained in:
parent
37fffc6e8f
commit
3c06511e91
@ -264,6 +264,24 @@ public:
|
||||
SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
|
||||
SkFilterQuality = kNone_SkFilterQuality) const;
|
||||
|
||||
// Helper functions to convert to SkBitmap
|
||||
|
||||
enum LegacyBitmapMode {
|
||||
kRO_LegacyBitmapMode,
|
||||
kRW_LegacyBitmapMode,
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to create a bitmap with the same pixels as the image. The result will always be
|
||||
* a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here).
|
||||
*
|
||||
* If the mode is kRO (read-only), the resulting bitmap will be marked as immutable.
|
||||
*
|
||||
* On succcess, returns true. On failure, returns false and the bitmap parameter will be reset
|
||||
* to empty.
|
||||
*/
|
||||
bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
|
||||
|
||||
protected:
|
||||
SkImage(int width, int height) :
|
||||
fWidth(width),
|
||||
|
@ -257,6 +257,29 @@ SkImage* SkImage::NewFromBitmap(const SkBitmap& bm) {
|
||||
return SkNewImageFromRasterBitmap(bm, false, NULL);
|
||||
}
|
||||
|
||||
bool SkImage::asLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) const {
|
||||
return as_IB(this)->onAsLegacyBitmap(bitmap, mode);
|
||||
}
|
||||
|
||||
bool SkImage_Base::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) const {
|
||||
// As the base-class, all we can do is make a copy (regardless of mode).
|
||||
// Subclasses that want to be more optimal should override.
|
||||
SkImageInfo info = SkImageInfo::MakeN32(this->width(), this->height(),
|
||||
this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
|
||||
if (!bitmap->tryAllocPixels(info)) {
|
||||
return false;
|
||||
}
|
||||
if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) {
|
||||
bitmap->reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kRO_LegacyBitmapMode == mode) {
|
||||
bitmap->setImmutable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !SK_SUPPORT_GPU
|
||||
|
@ -61,6 +61,8 @@ public:
|
||||
SkFilterQuality) const;
|
||||
virtual SkData* onRefEncoded() const { return NULL; }
|
||||
|
||||
virtual bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
|
||||
|
||||
private:
|
||||
const SkSurfaceProps fProps;
|
||||
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
const SkMatrix* localMatrix) const override;
|
||||
|
||||
bool isOpaque() const override;
|
||||
bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const override;
|
||||
|
||||
SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props)
|
||||
: INHERITED(bm.width(), bm.height(), props)
|
||||
@ -262,3 +263,17 @@ bool SkImage_Raster::isOpaque() const {
|
||||
return fBitmap.isOpaque();
|
||||
}
|
||||
|
||||
bool SkImage_Raster::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) const {
|
||||
if (kRO_LegacyBitmapMode == mode) {
|
||||
// When we're a snapshot from a surface, our bitmap may not be marked immutable
|
||||
// even though logically always we are, but in that case we can't physically share our
|
||||
// pixelref since the caller might call setImmutable() themselves
|
||||
// (thus changing our state).
|
||||
if (fBitmap.isImmutable()) {
|
||||
bitmap->setInfo(fBitmap.info());
|
||||
bitmap->setPixelRef(fBitmap.pixelRef(), fBitmap.pixelRefOrigin());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this->INHERITED::onAsLegacyBitmap(bitmap, mode);
|
||||
}
|
||||
|
@ -407,6 +407,33 @@ static void test_image_readpixels(skiatest::Reporter* reporter, SkImage* image,
|
||||
REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
|
||||
}
|
||||
|
||||
static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image) {
|
||||
const SkImage::LegacyBitmapMode modes[] = {
|
||||
SkImage::kRO_LegacyBitmapMode,
|
||||
SkImage::kRW_LegacyBitmapMode,
|
||||
};
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
|
||||
SkBitmap bitmap;
|
||||
REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, modes[i]));
|
||||
|
||||
REPORTER_ASSERT(reporter, image->width() == bitmap.width());
|
||||
REPORTER_ASSERT(reporter, image->height() == bitmap.height());
|
||||
REPORTER_ASSERT(reporter, image->isOpaque() == bitmap.isOpaque());
|
||||
|
||||
bitmap.lockPixels();
|
||||
REPORTER_ASSERT(reporter, bitmap.getPixels());
|
||||
|
||||
const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
|
||||
SkPMColor imageColor;
|
||||
REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMColor), 0, 0));
|
||||
REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
|
||||
|
||||
if (SkImage::kRO_LegacyBitmapMode == modes[i]) {
|
||||
REPORTER_ASSERT(reporter, bitmap.isImmutable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
|
||||
static const struct {
|
||||
ImageType fType;
|
||||
@ -450,6 +477,8 @@ static void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* facto
|
||||
REPORTER_ASSERT(reporter, NULL == releaseCtx.fData); // we ignored the context
|
||||
}
|
||||
|
||||
test_legacy_bitmap(reporter, image);
|
||||
|
||||
const void* addr = image->peekPixels(&info, &rowBytes);
|
||||
bool success = SkToBool(addr);
|
||||
REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
|
||||
|
Loading…
Reference in New Issue
Block a user