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,
|
SkImage* newImage(int newWidth, int newHeight, const SkIRect* subset = NULL,
|
||||||
SkFilterQuality = kNone_SkFilterQuality) const;
|
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:
|
protected:
|
||||||
SkImage(int width, int height) :
|
SkImage(int width, int height) :
|
||||||
fWidth(width),
|
fWidth(width),
|
||||||
|
@ -257,6 +257,29 @@ SkImage* SkImage::NewFromBitmap(const SkBitmap& bm) {
|
|||||||
return SkNewImageFromRasterBitmap(bm, false, NULL);
|
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
|
#if !SK_SUPPORT_GPU
|
||||||
|
@ -61,6 +61,8 @@ public:
|
|||||||
SkFilterQuality) const;
|
SkFilterQuality) const;
|
||||||
virtual SkData* onRefEncoded() const { return NULL; }
|
virtual SkData* onRefEncoded() const { return NULL; }
|
||||||
|
|
||||||
|
virtual bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SkSurfaceProps fProps;
|
const SkSurfaceProps fProps;
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ public:
|
|||||||
const SkMatrix* localMatrix) const override;
|
const SkMatrix* localMatrix) const override;
|
||||||
|
|
||||||
bool isOpaque() const override;
|
bool isOpaque() const override;
|
||||||
|
bool onAsLegacyBitmap(SkBitmap*, LegacyBitmapMode) const override;
|
||||||
|
|
||||||
SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props)
|
SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props)
|
||||||
: INHERITED(bm.width(), bm.height(), props)
|
: INHERITED(bm.width(), bm.height(), props)
|
||||||
@ -262,3 +263,17 @@ bool SkImage_Raster::isOpaque() const {
|
|||||||
return fBitmap.isOpaque();
|
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));
|
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 void test_imagepeek(skiatest::Reporter* reporter, GrContextFactory* factory) {
|
||||||
static const struct {
|
static const struct {
|
||||||
ImageType fType;
|
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
|
REPORTER_ASSERT(reporter, NULL == releaseCtx.fData); // we ignored the context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_legacy_bitmap(reporter, image);
|
||||||
|
|
||||||
const void* addr = image->peekPixels(&info, &rowBytes);
|
const void* addr = image->peekPixels(&info, &rowBytes);
|
||||||
bool success = SkToBool(addr);
|
bool success = SkToBool(addr);
|
||||||
REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
|
REPORTER_ASSERT(reporter, gRec[i].fPeekShouldSucceed == success);
|
||||||
|
Loading…
Reference in New Issue
Block a user