Move Ganesh Skp texture code into GrImageUtils
This is a follow-up to http://review.skia.org/673717 which
makes SkPictureImageGenerator Ganesh-agnostic (and moves it
to src/image/ so it can be closer to its friends).
Change-Id: I61e0e8d5e026fd782da9651c4d90be51daee0734
Bug: skia:13983
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/678656
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/core.gni b/gn/core.gni
index 0930db0..a24a9fc 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -597,9 +597,13 @@
"$_src/image/SkImage_Lazy.cpp",
"$_src/image/SkImage_Lazy.h",
"$_src/image/SkImage_LazyFactories.cpp",
+ "$_src/image/SkImage_Picture.cpp",
+ "$_src/image/SkImage_Picture.h",
"$_src/image/SkImage_Raster.cpp",
"$_src/image/SkImage_Raster.h",
"$_src/image/SkImage_RasterFactories.cpp",
+ "$_src/image/SkPictureImageGenerator.cpp",
+ "$_src/image/SkPictureImageGenerator.h",
"$_src/image/SkRescaleAndReadPixels.cpp",
"$_src/image/SkRescaleAndReadPixels.h",
"$_src/image/SkSurface.cpp",
@@ -726,7 +730,6 @@
"$_src/core/SkPictureData.h",
"$_src/core/SkPictureFlat.cpp",
"$_src/core/SkPictureFlat.h",
- "$_src/core/SkPictureImageGenerator.cpp",
"$_src/core/SkPicturePlayback.cpp",
"$_src/core/SkPicturePlayback.h",
"$_src/core/SkPictureRecord.cpp",
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 8f7d4a4..1dc696d 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -1021,7 +1021,7 @@
example: https://fiddle.skia.org/c/@Image_isLazyGenerated_a
example: https://fiddle.skia.org/c/@Image_isLazyGenerated_b
*/
- bool isLazyGenerated() const;
+ virtual bool isLazyGenerated() const = 0;
/** Creates SkImage in target SkColorSpace.
Returns nullptr if SkImage could not be created.
diff --git a/public.bzl b/public.bzl
index c73f52f..5b4e056 100644
--- a/public.bzl
+++ b/public.bzl
@@ -547,7 +547,6 @@
"src/core/SkPictureData.h",
"src/core/SkPictureFlat.cpp",
"src/core/SkPictureFlat.h",
- "src/core/SkPictureImageGenerator.cpp",
"src/core/SkPicturePlayback.cpp",
"src/core/SkPicturePlayback.h",
"src/core/SkPicturePriv.h",
@@ -1232,9 +1231,13 @@
"src/image/SkImage_Lazy.cpp",
"src/image/SkImage_Lazy.h",
"src/image/SkImage_LazyFactories.cpp",
+ "src/image/SkImage_Picture.cpp",
+ "src/image/SkImage_Picture.h",
"src/image/SkImage_Raster.cpp",
"src/image/SkImage_Raster.h",
"src/image/SkImage_RasterFactories.cpp",
+ "src/image/SkPictureImageGenerator.cpp",
+ "src/image/SkPictureImageGenerator.h",
"src/image/SkRescaleAndReadPixels.cpp",
"src/image/SkRescaleAndReadPixels.h",
"src/image/SkSurface.cpp",
diff --git a/src/core/BUILD.bazel b/src/core/BUILD.bazel
index 5539fc6..c9a60f2 100644
--- a/src/core/BUILD.bazel
+++ b/src/core/BUILD.bazel
@@ -394,7 +394,6 @@
"SkPictureData.h",
"SkPictureFlat.cpp",
"SkPictureFlat.h",
- "SkPictureImageGenerator.cpp",
"SkPicturePlayback.cpp",
"SkPicturePlayback.h",
"SkPictureRecord.cpp",
diff --git a/src/core/SkPictureImageGenerator.cpp b/src/core/SkPictureImageGenerator.cpp
deleted file mode 100644
index 4177cbf..0000000
--- a/src/core/SkPictureImageGenerator.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkCanvas.h"
-#include "include/core/SkColorSpace.h"
-#include "include/core/SkImageGenerator.h"
-#include "include/core/SkMatrix.h"
-#include "include/core/SkPaint.h"
-#include "include/core/SkPicture.h"
-#include "include/core/SkSurface.h"
-#include "src/base/SkTLazy.h"
-#include "src/image/SkImageGeneratorPriv.h"
-#include "src/image/SkImage_Base.h"
-
-#if defined(SK_GANESH)
-#include "include/gpu/ganesh/GrTextureGenerator.h"
-#include "src/gpu/ganesh/GrTextureProxy.h"
-#include "src/gpu/ganesh/image/GrImageUtils.h"
-#endif
-
-
-#if defined(SK_GANESH)
-using BASE_CLASS = GrTextureGenerator;
-#else
-using BASE_CLASS = SkImageGenerator;
-#endif
-
-class SkPictureImageGenerator : public BASE_CLASS {
-public:
- SkPictureImageGenerator(const SkImageInfo&, sk_sp<SkPicture>, const SkMatrix*,
- const SkPaint*, const SkSurfaceProps&);
-
-protected:
- bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&) override;
-
-#if defined(SK_GANESH)
- GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,
- GrMipmapped, GrImageTexGenPolicy) override;
-#endif
-
-#if defined(SK_GRAPHITE)
- sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*,
- const SkImageInfo&,
- skgpu::Mipmapped) override;
-#endif
-
-private:
- sk_sp<SkPicture> fPicture;
- SkMatrix fMatrix;
- SkTLazy<SkPaint> fPaint;
- SkSurfaceProps fProps;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace SkImageGenerators {
-std::unique_ptr<SkImageGenerator> MakeFromPicture(
- const SkISize& size,
- sk_sp<SkPicture> picture,
- const SkMatrix* matrix,
- const SkPaint* paint,
- SkImages::BitDepth bitDepth,
- sk_sp<SkColorSpace> colorSpace) {
- return MakeFromPicture(size, picture, matrix, paint, bitDepth, colorSpace, {});
-}
-
-std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize& size,
- sk_sp<SkPicture> picture,
- const SkMatrix* matrix,
- const SkPaint* paint,
- SkImages::BitDepth bitDepth,
- sk_sp<SkColorSpace> colorSpace,
- SkSurfaceProps props) {
- if (!picture || !colorSpace || size.isEmpty()) {
- return nullptr;
- }
-
- SkColorType colorType = kN32_SkColorType;
- if (SkImages::BitDepth::kF16 == bitDepth) {
- colorType = kRGBA_F16_SkColorType;
- }
-
- SkImageInfo info =
- SkImageInfo::Make(size, colorType, kPremul_SkAlphaType, std::move(colorSpace));
- return std::unique_ptr<SkImageGenerator>(
- new SkPictureImageGenerator(info, std::move(picture), matrix, paint, props));
-}
-} // SkImageGenerators
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
- const SkMatrix* matrix, const SkPaint* paint,
- const SkSurfaceProps& props)
- : BASE_CLASS(info)
- , fPicture(std::move(picture))
- , fProps(props) {
-
- if (matrix) {
- fMatrix = *matrix;
- } else {
- fMatrix.reset();
- }
-
- if (paint) {
- fPaint.set(*paint);
- }
-}
-
-bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- const Options& opts) {
- std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &fProps);
- if (!canvas) {
- return false;
- }
- canvas->clear(0);
- canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if defined(SK_GANESH)
-#include "include/gpu/GrRecordingContext.h"
-#include "src/gpu/ganesh/GrRecordingContextPriv.h"
-#include "src/gpu/ganesh/SkGr.h"
-
-GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
- const SkImageInfo& info,
- GrMipmapped mipmapped,
- GrImageTexGenPolicy texGenPolicy) {
- SkASSERT(ctx);
-
- skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
- ? skgpu::Budgeted::kNo
- : skgpu::Budgeted::kYes;
- auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
- &fProps, mipmapped == GrMipmapped::kYes);
- if (!surface) {
- return {};
- }
-
- surface->getCanvas()->clear(SkColors::kTransparent);
- surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
- sk_sp<SkImage> image(surface->makeImageSnapshot());
- if (!image) {
- return {};
- }
-
- auto [view, ct] = skgpu::ganesh::AsView(ctx, image, mipmapped);
- SkASSERT(view);
- SkASSERT(mipmapped == GrMipmapped::kNo ||
- view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
- return view;
-}
-
-#endif // defined(SK_GANESH)
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if defined(SK_GRAPHITE)
-#include "src/gpu/graphite/Log.h"
-
-sk_sp<SkImage> SkPictureImageGenerator::onMakeTextureImage(skgpu::graphite::Recorder* recorder,
- const SkImageInfo& info,
- skgpu::Mipmapped mipmapped) {
- using namespace skgpu::graphite;
-
- sk_sp<SkSurface> surface = SkSurface::MakeGraphite(recorder, info, mipmapped);
- if (!surface) {
- SKGPU_LOG_E("Failed to create Surface");
- return nullptr;
- }
-
- surface->getCanvas()->clear(SkColors::kTransparent);
- surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
- return surface->asImage();
-}
-
-#endif // SK_GRAPHITE
diff --git a/src/gpu/ganesh/image/GrImageUtils.cpp b/src/gpu/ganesh/image/GrImageUtils.cpp
index c6e758d..0702f65 100644
--- a/src/gpu/ganesh/image/GrImageUtils.cpp
+++ b/src/gpu/ganesh/image/GrImageUtils.cpp
@@ -9,6 +9,8 @@
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
@@ -16,6 +18,7 @@
#include "include/core/SkRect.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
+#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
@@ -53,6 +56,7 @@
#include "src/gpu/ganesh/image/SkImage_RasterPinnable.h"
#include "src/image/SkImage_Base.h"
#include "src/image/SkImage_Lazy.h"
+#include "src/image/SkImage_Picture.h"
#include "src/image/SkImage_Raster.h"
#include <string_view>
@@ -219,6 +223,41 @@
return sfc->readSurfaceView();
}
+static GrSurfaceProxyView generate_picture_texture(GrRecordingContext* ctx,
+ const SkImage_Picture* img,
+ GrMipmapped mipmapped,
+ GrImageTexGenPolicy texGenPolicy) {
+ SkASSERT(ctx);
+ SkASSERT(img);
+
+ auto sharedGenerator = img->generator();
+ SkAutoMutexExclusive mutex(sharedGenerator->fMutex);
+
+ skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? skgpu::Budgeted::kNo
+ : skgpu::Budgeted::kYes;
+ auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, img->imageInfo(), 0,
+ kTopLeft_GrSurfaceOrigin,
+ img->props(), mipmapped == GrMipmapped::kYes);
+ if (!surface) {
+ return {};
+ }
+
+ surface->getCanvas()->clear(SkColors::kTransparent);
+ surface->getCanvas()->drawPicture(img->picture(), img->matrix(), img->paint());
+ sk_sp<SkImage> image(surface->makeImageSnapshot());
+ if (!image) {
+ return {};
+ }
+
+ auto [view, ct] = AsView(ctx, image, mipmapped);
+ SkASSERT(view);
+ SkASSERT(mipmapped == GrMipmapped::kNo ||
+ view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
+ return view;
+}
+
+
// Returns the texture proxy. We will always cache the generated texture on success.
// We have 4 ways to try to return a texture (in sorted order)
//
@@ -292,7 +331,15 @@
// 2. Ask the generator to natively create one (if it knows how)
{
- if (img->generator()->isTextureGenerator()) {
+ if (img->type() == SkImage_Base::Type::kLazyPicture) {
+ if (auto view = generate_picture_texture(rContext,
+ static_cast<const SkImage_Picture*>(img),
+ mipmapped,
+ texGenPolicy)) {
+ installKey(view);
+ return view;
+ }
+ } else if (img->generator()->isTextureGenerator()) {
auto sharedGenerator = img->generator();
SkAutoMutexExclusive mutex(sharedGenerator->fMutex);
auto textureGen = static_cast<GrTextureGenerator*>(sharedGenerator->fGenerator.get());
diff --git a/src/image/BUILD.bazel b/src/image/BUILD.bazel
index 93dcad9..7e29553 100644
--- a/src/image/BUILD.bazel
+++ b/src/image/BUILD.bazel
@@ -12,9 +12,13 @@
"SkImage_Lazy.cpp",
"SkImage_Lazy.h",
"SkImage_LazyFactories.cpp",
+ "SkImage_Picture.cpp",
+ "SkImage_Picture.h",
"SkImage_Raster.cpp",
"SkImage_Raster.h",
"SkImage_RasterFactories.cpp",
+ "SkPictureImageGenerator.cpp",
+ "SkPictureImageGenerator.h",
"SkRescaleAndReadPixels.cpp",
"SkRescaleAndReadPixels.h",
"SkSurface.cpp",
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index ee231e4..5c37cc3 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -312,10 +312,6 @@
return result->asImage();
}
-bool SkImage::isLazyGenerated() const {
- return as_IB(this)->onIsLazyGenerated();
-}
-
bool SkImage::isAlphaOnly() const { return SkColorTypeIsAlphaOnly(fInfo.colorType()); }
sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target, GrDirectContext* direct) const {
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 923cd0a..b94ed99 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -129,6 +129,7 @@
kRaster,
kRasterPinnable,
kLazy,
+ kLazyPicture,
kGanesh,
kGaneshYUVA,
kGraphite,
@@ -138,7 +139,9 @@
virtual Type type() const = 0;
// True for picture-backed and codec-backed
- bool onIsLazyGenerated() const { return this->type() == Type::kLazy; }
+ bool isLazyGenerated() const override {
+ return this->type() == Type::kLazy || this->type() == Type::kLazyPicture;
+ }
bool isRasterBacked() const {
return this->type() == Type::kRaster || this->type() == Type::kRasterPinnable;
diff --git a/src/image/SkImage_Lazy.h b/src/image/SkImage_Lazy.h
index 4ae2e67..561e98e 100644
--- a/src/image/SkImage_Lazy.h
+++ b/src/image/SkImage_Lazy.h
@@ -83,7 +83,6 @@
// Be careful with this. You need to acquire the mutex, as the generator might be shared
// among several images.
- //std::unique_ptr<SkImageGenerator> generator() const;
sk_sp<SharedGenerator> generator() const;
protected:
virtual bool readPixelsProxy(GrDirectContext*, const SkPixmap&) const { return false; }
diff --git a/src/image/SkImage_LazyFactories.cpp b/src/image/SkImage_LazyFactories.cpp
index bbb4fcf..526e9c8 100644
--- a/src/image/SkImage_LazyFactories.cpp
+++ b/src/image/SkImage_LazyFactories.cpp
@@ -12,8 +12,7 @@
#include "include/core/SkPicture.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceProps.h"
-
-#include "src/image/SkImageGeneratorPriv.h"
+#include "src/image/SkImage_Picture.h"
#include <optional>
#include <utility>
@@ -39,8 +38,8 @@
const SkPaint* paint,
BitDepth bitDepth,
sk_sp<SkColorSpace> colorSpace) {
- return DeferredFromPicture(std::move(picture), dimensions, matrix, paint, bitDepth,
- std::move(colorSpace), {});
+ return SkImage_Picture::Make(std::move(picture), dimensions, matrix, paint, bitDepth,
+ std::move(colorSpace), {});
}
sk_sp<SkImage> DeferredFromPicture(sk_sp<SkPicture> picture,
@@ -50,8 +49,8 @@
BitDepth bitDepth,
sk_sp<SkColorSpace> colorSpace,
SkSurfaceProps props) {
- return DeferredFromGenerator(SkImageGenerators::MakeFromPicture(
- dimensions, std::move(picture), matrix, paint, bitDepth, std::move(colorSpace), props));
+ return SkImage_Picture::Make(std::move(picture), dimensions, matrix, paint, bitDepth,
+ std::move(colorSpace), props);
}
} // namespace SkImages
diff --git a/src/image/SkImage_Picture.cpp b/src/image/SkImage_Picture.cpp
new file mode 100644
index 0000000..5c80bb4
--- /dev/null
+++ b/src/image/SkImage_Picture.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/image/SkImage_Picture.h"
+
+#include "include/core/SkColorSpace.h"
+#include "include/core/SkImage.h"
+#include "include/core/SkImageGenerator.h"
+#include "include/core/SkPicture.h"
+#include "include/core/SkSurfaceProps.h"
+#include "src/base/SkTLazy.h"
+#include "src/image/SkImageGeneratorPriv.h"
+#include "src/image/SkImage_Lazy.h"
+#include "src/image/SkPictureImageGenerator.h"
+
+#include <memory>
+#include <utility>
+
+class SkMatrix;
+class SkPaint;
+struct SkISize;
+
+sk_sp<SkImage> SkImage_Picture::Make(sk_sp<SkPicture> picture, const SkISize& dimensions,
+ const SkMatrix* matrix, const SkPaint* paint,
+ SkImages::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace,
+ SkSurfaceProps props) {
+ auto gen = SkImageGenerators::MakeFromPicture(dimensions, std::move(picture), matrix, paint,
+ bitDepth, std::move(colorSpace), props);
+
+ SkImage_Lazy::Validator validator(
+ SharedGenerator::Make(std::move(gen)), nullptr, nullptr);
+
+ return validator ? sk_make_sp<SkImage_Picture>(&validator) : nullptr;
+}
+
+SkPictureImageGenerator* SkImage_Picture::gen() const {
+ return static_cast<SkPictureImageGenerator*>(this->generator()->fGenerator.get());
+}
+
+SkPicture* SkImage_Picture::picture() const {
+ return this->gen()->fPicture.get();
+}
+
+SkMatrix* SkImage_Picture::matrix() const {
+ return &this->gen()->fMatrix;
+}
+
+SkPaint* SkImage_Picture::paint() const {
+ return this->gen()->fPaint.getMaybeNull();
+}
+
+SkSurfaceProps* SkImage_Picture::props() const {
+ return &this->gen()->fProps;
+}
diff --git a/src/image/SkImage_Picture.h b/src/image/SkImage_Picture.h
new file mode 100644
index 0000000..cb2eefe
--- /dev/null
+++ b/src/image/SkImage_Picture.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkImage_Picture_DEFINED
+#define SkImage_Picture_DEFINED
+
+#include "include/core/SkRefCnt.h"
+#include "src/image/SkImage_Base.h"
+#include "src/image/SkImage_Lazy.h"
+
+class SkColorSpace;
+class SkImage;
+class SkMatrix;
+class SkPaint;
+class SkPicture;
+class SkPictureImageGenerator;
+class SkSurfaceProps;
+struct SkISize;
+
+namespace SkImages { enum class BitDepth; }
+
+class SkImage_Picture : public SkImage_Lazy {
+public:
+ static sk_sp<SkImage> Make(sk_sp<SkPicture> picture, const SkISize& dimensions,
+ const SkMatrix* matrix, const SkPaint* paint,
+ SkImages::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace,
+ SkSurfaceProps props);
+
+ SkImage_Picture(Validator* validator) : SkImage_Lazy(validator) {}
+
+ SkImage_Base::Type type() const override { return SkImage_Base::Type::kLazyPicture; }
+
+ // These are not necessarily thread-safe. Be sure to grab the mutex from the shared
+ // generator before accessing them.
+ SkPicture* picture() const;
+ SkMatrix* matrix() const;
+ SkPaint* paint() const;
+ SkSurfaceProps* props() const;
+
+private:
+ SkPictureImageGenerator* gen() const;
+};
+
+#endif
diff --git a/src/image/SkPictureImageGenerator.cpp b/src/image/SkPictureImageGenerator.cpp
new file mode 100644
index 0000000..864fad9
--- /dev/null
+++ b/src/image/SkPictureImageGenerator.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/image/SkPictureImageGenerator.h"
+
+#include "include/core/SkAlphaType.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColorSpace.h"
+#include "include/core/SkColorType.h"
+#include "include/core/SkImage.h"
+#include "include/core/SkImageGenerator.h"
+#include "include/core/SkImageInfo.h"
+#include "include/core/SkMatrix.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPicture.h"
+#include "include/core/SkSize.h"
+#include "src/base/SkTLazy.h"
+#include "src/image/SkImageGeneratorPriv.h"
+
+#include <memory>
+#include <utility>
+
+namespace SkImageGenerators {
+std::unique_ptr<SkImageGenerator> MakeFromPicture(
+ const SkISize& size,
+ sk_sp<SkPicture> picture,
+ const SkMatrix* matrix,
+ const SkPaint* paint,
+ SkImages::BitDepth bitDepth,
+ sk_sp<SkColorSpace> colorSpace) {
+ return MakeFromPicture(size, picture, matrix, paint, bitDepth, colorSpace, {});
+}
+
+std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize& size,
+ sk_sp<SkPicture> picture,
+ const SkMatrix* matrix,
+ const SkPaint* paint,
+ SkImages::BitDepth bitDepth,
+ sk_sp<SkColorSpace> colorSpace,
+ SkSurfaceProps props) {
+ if (!picture || !colorSpace || size.isEmpty()) {
+ return nullptr;
+ }
+
+ SkColorType colorType = kN32_SkColorType;
+ if (SkImages::BitDepth::kF16 == bitDepth) {
+ colorType = kRGBA_F16_SkColorType;
+ }
+
+ SkImageInfo info =
+ SkImageInfo::Make(size, colorType, kPremul_SkAlphaType, std::move(colorSpace));
+ return std::unique_ptr<SkImageGenerator>(
+ new SkPictureImageGenerator(info, std::move(picture), matrix, paint, props));
+}
+} // SkImageGenerators
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
+ const SkMatrix* matrix, const SkPaint* paint,
+ const SkSurfaceProps& props)
+ : SkImageGenerator(info)
+ , fPicture(std::move(picture))
+ , fProps(props) {
+
+ if (matrix) {
+ fMatrix = *matrix;
+ } else {
+ fMatrix.reset();
+ }
+
+ if (paint) {
+ fPaint.set(*paint);
+ }
+}
+
+bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ const Options& opts) {
+ std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &fProps);
+ if (!canvas) {
+ return false;
+ }
+ canvas->clear(0);
+ canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
+ return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if defined(SK_GRAPHITE)
+#include "include/core/SkSurface.h"
+#include "src/gpu/graphite/Log.h"
+
+sk_sp<SkImage> SkPictureImageGenerator::onMakeTextureImage(skgpu::graphite::Recorder* recorder,
+ const SkImageInfo& info,
+ skgpu::Mipmapped mipmapped) {
+ using namespace skgpu::graphite;
+
+ sk_sp<SkSurface> surface = SkSurface::MakeGraphite(recorder, info, mipmapped);
+ if (!surface) {
+ SKGPU_LOG_E("Failed to create Surface");
+ return nullptr;
+ }
+
+ surface->getCanvas()->clear(SkColors::kTransparent);
+ surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
+ return surface->asImage();
+}
+
+#endif // SK_GRAPHITE
diff --git a/src/image/SkPictureImageGenerator.h b/src/image/SkPictureImageGenerator.h
new file mode 100644
index 0000000..6f5e7c0
--- /dev/null
+++ b/src/image/SkPictureImageGenerator.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPictureImageGenerator_DEFINED
+#define SkPictureImageGenerator_DEFINED
+
+#include "include/core/SkImageGenerator.h"
+#include "include/core/SkMatrix.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPicture.h"
+#include "include/core/SkRefCnt.h"
+#include "include/core/SkSurfaceProps.h"
+#include "src/base/SkTLazy.h"
+
+#include <cstddef>
+
+struct SkImageInfo;
+
+class SkPictureImageGenerator : public SkImageGenerator {
+public:
+ SkPictureImageGenerator(const SkImageInfo&, sk_sp<SkPicture>, const SkMatrix*,
+ const SkPaint*, const SkSurfaceProps&);
+
+protected:
+ bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&) override;
+
+#if defined(SK_GRAPHITE)
+ sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*,
+ const SkImageInfo&,
+ skgpu::Mipmapped) override;
+#endif
+
+private:
+ sk_sp<SkPicture> fPicture;
+ SkMatrix fMatrix;
+ SkTLazy<SkPaint> fPaint;
+ SkSurfaceProps fProps;
+
+ friend class SkImage_Picture;
+};
+
+#endif