From e94255d456ad86e045e0c3aeab57395566cf49a5 Mon Sep 17 00:00:00 2001 From: Matt Sarett Date: Mon, 9 Jan 2017 12:38:59 -0500 Subject: [PATCH] Specify bit depth and color space in SkImage::MakeFromPicture() BUG=skia: Change-Id: I1d2a2b1f97557fc3e7ca6c2bdad6329f7760dbd2 Reviewed-on: https://skia-review.googlesource.com/6685 Commit-Queue: Matt Sarett Reviewed-by: Mike Reed --- gm/image.cpp | 3 ++- gm/image_pict.cpp | 7 +++++-- gm/image_shader.cpp | 1 + gm/pictureimagegenerator.cpp | 2 +- gm/verylargebitmap.cpp | 1 + include/core/SkImage.h | 21 +++++++++++++++------ include/core/SkImageGenerator.h | 5 ++--- src/core/SkPictureImageGenerator.cpp | 25 ++++++++++++++++--------- src/core/SkPictureShader.cpp | 2 +- src/image/SkImage.cpp | 20 ++++++++++---------- tests/ImageIsOpaqueTest.cpp | 1 + tests/ImageTest.cpp | 2 +- tests/SkResourceCacheTest.cpp | 1 + 13 files changed, 57 insertions(+), 34 deletions(-) diff --git a/gm/image.cpp b/gm/image.cpp index 0bdd994..595a5ef 100644 --- a/gm/image.cpp +++ b/gm/image.cpp @@ -246,7 +246,7 @@ static sk_sp make_picture(const SkImageInfo& info, GrContext*, void (*d SkPictureRecorder recorder; draw(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height()))); return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), - info.dimensions(), nullptr, nullptr, + info.dimensions(), nullptr, nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } @@ -345,6 +345,7 @@ static SkImageGenerator* gen_picture(const SkImageInfo& info) { draw_opaque_contents(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height()))); sk_sp pict(recorder.finishRecordingAsPicture()); return SkImageGenerator::NewFromPicture(info.dimensions(), pict.get(), nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp index 229f3c5..1fdff21 100644 --- a/gm/image_pict.cpp +++ b/gm/image_pict.cpp @@ -66,11 +66,13 @@ protected: SkMatrix matrix; matrix.setTranslate(-100, -100); - fImage0 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, srgbColorSpace); + fImage0 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, + SkImage::BitDepth::kU8, srgbColorSpace); matrix.postTranslate(-50, -50); matrix.postRotate(45); matrix.postTranslate(50, 50); - fImage1 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, srgbColorSpace); + fImage1 = SkImage::MakeFromPicture(fPicture, size, &matrix, nullptr, + SkImage::BitDepth::kU8, srgbColorSpace); } void drawSet(SkCanvas* canvas) const { @@ -109,6 +111,7 @@ static SkImageGenerator* make_pic_generator(GrContext*, SkPicture* pic) { SkMatrix matrix; matrix.setTranslate(-100, -100); return SkImageGenerator::NewFromPicture(SkISize::Make(100, 100), pic, &matrix, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } diff --git a/gm/image_shader.cpp b/gm/image_shader.cpp index 7803739..522d373 100644 --- a/gm/image_shader.cpp +++ b/gm/image_shader.cpp @@ -48,6 +48,7 @@ static sk_sp make_texture(GrContext* ctx, SkPicture* pic, const SkImage static sk_sp make_pict_gen(GrContext*, SkPicture* pic, const SkImageInfo& info) { return SkImage::MakeFromPicture(sk_ref_sp(pic), info.dimensions(), nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } diff --git a/gm/pictureimagegenerator.cpp b/gm/pictureimagegenerator.cpp index b247af2..accf072 100644 --- a/gm/pictureimagegenerator.cpp +++ b/gm/pictureimagegenerator.cpp @@ -156,7 +156,7 @@ protected: std::unique_ptr gen( SkImageGenerator::NewFromPicture(configs[i].size, fPicture.get(), &m, p.getAlpha() != 255 ? &p : nullptr, - srgbColorSpace)); + SkImage::BitDepth::kU8, srgbColorSpace)); SkImageInfo bmInfo = gen->getInfo().makeColorSpace( sk_ref_sp(canvas->imageInfo().colorSpace())); diff --git a/gm/verylargebitmap.cpp b/gm/verylargebitmap.cpp index 280d117..449b229 100644 --- a/gm/verylargebitmap.cpp +++ b/gm/verylargebitmap.cpp @@ -33,6 +33,7 @@ static sk_sp make_picture_image(int width, int height, SkColor colors[2 draw(recorder.beginRecording(SkRect::MakeIWH(width, height)), width, height, colors); return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(width, height), nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 19ea8b8..7d282da 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -154,15 +154,24 @@ public: const SkISize nv12Sizes[2], GrSurfaceOrigin, sk_sp = nullptr); - /** - * Create a new image from the specified picture. The color space becomes a preferred - * color space for playback of the picture when retrieving the rasterized image contents. - */ - static sk_sp MakeFromPicture(sk_sp, const SkISize& dimensions, - const SkMatrix*, const SkPaint*, sk_sp); + enum class BitDepth { + kU8, + kF16, + }; +#ifdef SK_USE_LEGACY_MAKE_PICTURE_API static sk_sp MakeFromPicture(sk_sp picture, const SkISize& dimensions, const SkMatrix* matrix, const SkPaint* paint); +#endif + + /** + * Create a new image from the specified picture. + * Creating an SkImage from an SkPicture requires snapping the picture to a particular + * BitDepth and SkColorSpace. + */ + static sk_sp MakeFromPicture(sk_sp, const SkISize& dimensions, + const SkMatrix*, const SkPaint*, BitDepth, + sk_sp); static sk_sp MakeTextureFromPixmap(GrContext*, const SkPixmap&, SkBudgeted budgeted); diff --git a/include/core/SkImageGenerator.h b/include/core/SkImageGenerator.h index 0ab27ae..aec940f 100644 --- a/include/core/SkImageGenerator.h +++ b/include/core/SkImageGenerator.h @@ -10,6 +10,7 @@ #include "SkBitmap.h" #include "SkColor.h" +#include "SkImage.h" #include "SkImageInfo.h" #include "SkYUVSizeInfo.h" @@ -19,8 +20,6 @@ class GrTexture; class GrSamplerParams; class SkBitmap; class SkData; -class SkImage; -class SkImageGenerator; class SkMatrix; class SkPaint; class SkPicture; @@ -228,7 +227,7 @@ public: * time. */ static SkImageGenerator* NewFromPicture(const SkISize&, const SkPicture*, const SkMatrix*, - const SkPaint*, sk_sp); + const SkPaint*, SkImage::BitDepth, sk_sp); bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator); diff --git a/src/core/SkPictureImageGenerator.cpp b/src/core/SkPictureImageGenerator.cpp index 4de49f0..3a4749b 100644 --- a/src/core/SkPictureImageGenerator.cpp +++ b/src/core/SkPictureImageGenerator.cpp @@ -17,7 +17,7 @@ class SkPictureImageGenerator : SkImageGenerator { public: static SkImageGenerator* Create(const SkISize&, const SkPicture*, const SkMatrix*, - const SkPaint*, sk_sp); + const SkPaint*, SkImage::BitDepth, sk_sp); protected: bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[], @@ -42,20 +42,25 @@ private: SkImageGenerator* SkPictureImageGenerator::Create(const SkISize& size, const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint, + SkImage::BitDepth bitDepth, sk_sp colorSpace) { - if (!picture || size.isEmpty()) { + if (!picture || size.isEmpty() || !colorSpace) { return nullptr; } - SkColorType colorType; - if (!colorSpace || colorSpace->gammaCloseToSRGB()) { - colorType = kN32_SkColorType; - } else if (colorSpace->gammaIsLinear()) { - colorType = kRGBA_F16_SkColorType; - } else { + if (SkImage::BitDepth::kF16 == bitDepth && !colorSpace->gammaIsLinear()) { + return nullptr; + } + + if (!colorSpace->gammaCloseToSRGB() && !colorSpace->gammaIsLinear()) { return nullptr; } + SkColorType colorType = kN32_SkColorType; + if (SkImage::BitDepth::kF16 == bitDepth) { + colorType = kRGBA_F16_SkColorType; + } + SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), colorType, kPremul_SkAlphaType, std::move(colorSpace)); return new SkPictureImageGenerator(info, picture, matrix, paint); @@ -134,8 +139,10 @@ bool SkPictureImageGenerator::onGenerateScaledPixels(const SkPixmap& scaledPixel SkImageGenerator* SkImageGenerator::NewFromPicture(const SkISize& size, const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint, + SkImage::BitDepth bitDepth, sk_sp colorSpace) { - return SkPictureImageGenerator::Create(size, picture, matrix, paint, std::move(colorSpace)); + return SkPictureImageGenerator::Create(size, picture, matrix, paint, bitDepth, + std::move(colorSpace)); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index e34ca99..1f20623 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -227,7 +227,7 @@ sk_sp SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, con sk_sp tileImage( SkImage::MakeFromPicture(fPicture, tileSize, &tileMatrix, nullptr, - sk_ref_sp(dstColorSpace))); + SkImage::BitDepth::kU8, sk_ref_sp(dstColorSpace))); if (!tileImage) { return nullptr; } diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 8a4fb29..f49a2ce 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -299,21 +299,21 @@ bool SkImage_Base::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) con return true; } +#ifdef SK_USE_LEGACY_MAKE_PICTURE_API sk_sp SkImage::MakeFromPicture(sk_sp picture, const SkISize& dimensions, - const SkMatrix* matrix, const SkPaint* paint, - sk_sp colorSpace) { - if (!picture) { - return nullptr; - } - return MakeFromGenerator(SkImageGenerator::NewFromPicture(dimensions, picture.get(), matrix, - paint, std::move(colorSpace))); + const SkMatrix* matrix, const SkPaint* paint) { + return SkImage::MakeFromPicture(std::move(picture), dimensions, matrix, paint, BitDepth::kU8, + SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); } +#endif sk_sp SkImage::MakeFromPicture(sk_sp picture, const SkISize& dimensions, - const SkMatrix* matrix, const SkPaint* paint) { - return MakeFromPicture(std::move(picture), dimensions, matrix, paint, nullptr); + const SkMatrix* matrix, const SkPaint* paint, + BitDepth bitDepth, sk_sp colorSpace) { + return MakeFromGenerator(SkImageGenerator::NewFromPicture(dimensions, picture.get(), matrix, + paint, bitDepth, + std::move(colorSpace))); } - sk_sp SkImage::makeWithFilter(const SkImageFilter* filter, const SkIRect& subset, const SkIRect& clipBounds, SkIRect* outSubset, SkIPoint* offset) const { diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp index 21ddb5d..cbbe331 100644 --- a/tests/ImageIsOpaqueTest.cpp +++ b/tests/ImageIsOpaqueTest.cpp @@ -125,6 +125,7 @@ DEF_TEST(Image_isAlphaOnly, reporter) { GetResourceAsImage("mandrill_128.png"), GetResourceAsImage("color_wheel.jpg"), SkImage::MakeFromPicture(make_picture(), { 10, 10 }, nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)), }) { diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 161dff8..4f9d944 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -130,7 +130,7 @@ static sk_sp create_picture_image() { SkCanvas* canvas = recorder.beginRecording(10, 10); canvas->clear(SK_ColorCYAN); return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(10, 10), - nullptr, nullptr, + nullptr, nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); }; #endif diff --git a/tests/SkResourceCacheTest.cpp b/tests/SkResourceCacheTest.cpp index ed2ff74..922acef 100644 --- a/tests/SkResourceCacheTest.cpp +++ b/tests/SkResourceCacheTest.cpp @@ -330,6 +330,7 @@ DEF_TEST(BitmapCache_discarded_image, reporter) { canvas->clear(SK_ColorCYAN); return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(10, 10), nullptr, nullptr, + SkImage::BitDepth::kU8, SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); }); } -- 2.7.4