From e72842a382b78ee5a239e1dc85eca662855c48b9 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 25 Apr 2023 10:02:39 -0400 Subject: [PATCH] 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 Reviewed-by: Brian Osman --- gn/core.gni | 5 +- include/core/SkImage.h | 2 +- public.bzl | 5 +- src/core/BUILD.bazel | 1 - src/gpu/ganesh/image/GrImageUtils.cpp | 49 +++++++++- src/image/BUILD.bazel | 4 + src/image/SkImage.cpp | 4 - src/image/SkImage_Base.h | 5 +- src/image/SkImage_Lazy.h | 1 - src/image/SkImage_LazyFactories.cpp | 11 +-- src/image/SkImage_Picture.cpp | 58 ++++++++++++ src/image/SkImage_Picture.h | 47 ++++++++++ .../SkPictureImageGenerator.cpp | 91 +++---------------- src/image/SkPictureImageGenerator.h | 46 ++++++++++ 14 files changed, 232 insertions(+), 97 deletions(-) create mode 100644 src/image/SkImage_Picture.cpp create mode 100644 src/image/SkImage_Picture.h rename src/{core => image}/SkPictureImageGenerator.cpp (56%) create mode 100644 src/image/SkPictureImageGenerator.h diff --git a/gn/core.gni b/gn/core.gni index 0930db0a7fd6..a24a9fc54fe4 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -597,9 +597,13 @@ skia_core_sources = [ "$_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 @@ skia_skpicture_sources = [ "$_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 8f7d4a46bd9d..1dc696d86102 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -1021,7 +1021,7 @@ class SK_API SkImage : public SkRefCnt { 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 c73f52f83e3c..5b4e056a7d6d 100644 --- a/public.bzl +++ b/public.bzl @@ -547,7 +547,6 @@ BASE_SRCS_ALL = [ "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 @@ BASE_SRCS_ALL = [ "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 5539fc6d0c66..c9a60f2eaf55 100644 --- a/src/core/BUILD.bazel +++ b/src/core/BUILD.bazel @@ -394,7 +394,6 @@ SKPICTURE_FILES = [ "SkPictureData.h", "SkPictureFlat.cpp", "SkPictureFlat.h", - "SkPictureImageGenerator.cpp", "SkPicturePlayback.cpp", "SkPicturePlayback.h", "SkPictureRecord.cpp", diff --git a/src/gpu/ganesh/image/GrImageUtils.cpp b/src/gpu/ganesh/image/GrImageUtils.cpp index c6e758d79949..0702f65cfb88 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 @@ -219,6 +223,41 @@ static GrSurfaceProxyView texture_proxy_view_from_planes(GrRecordingContext* ctx 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 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 @@ GrSurfaceProxyView LockTextureProxyView(GrRecordingContext* rContext, // 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(img), + mipmapped, + texGenPolicy)) { + installKey(view); + return view; + } + } else if (img->generator()->isTextureGenerator()) { auto sharedGenerator = img->generator(); SkAutoMutexExclusive mutex(sharedGenerator->fMutex); auto textureGen = static_cast(sharedGenerator->fGenerator.get()); diff --git a/src/image/BUILD.bazel b/src/image/BUILD.bazel index 93dcad952a15..7e29553b1b02 100644 --- a/src/image/BUILD.bazel +++ b/src/image/BUILD.bazel @@ -12,9 +12,13 @@ CORE_FILES = [ "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 ee231e4522dc..5c37cc3a9ac3 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -312,10 +312,6 @@ sk_sp SkImage::makeWithFilter(GrRecordingContext* rContext, const SkIma return result->asImage(); } -bool SkImage::isLazyGenerated() const { - return as_IB(this)->onIsLazyGenerated(); -} - bool SkImage::isAlphaOnly() const { return SkColorTypeIsAlphaOnly(fInfo.colorType()); } sk_sp SkImage::makeColorSpace(sk_sp target, GrDirectContext* direct) const { diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index 923cd0aa11c5..b94ed99d57c4 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -129,6 +129,7 @@ class SkImage_Base : public SkImage { kRaster, kRasterPinnable, kLazy, + kLazyPicture, kGanesh, kGaneshYUVA, kGraphite, @@ -138,7 +139,9 @@ class SkImage_Base : public SkImage { 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 4ae2e67be89f..561e98e3f25f 100644 --- a/src/image/SkImage_Lazy.h +++ b/src/image/SkImage_Lazy.h @@ -83,7 +83,6 @@ class SkImage_Lazy : public SkImage_Base { // Be careful with this. You need to acquire the mutex, as the generator might be shared // among several images. - //std::unique_ptr generator() const; sk_sp 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 bbb4fcf19c53..526e9c814527 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 #include @@ -39,8 +38,8 @@ sk_sp DeferredFromPicture(sk_sp picture, const SkPaint* paint, BitDepth bitDepth, sk_sp 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 DeferredFromPicture(sk_sp picture, @@ -50,8 +49,8 @@ sk_sp DeferredFromPicture(sk_sp picture, BitDepth bitDepth, sk_sp 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 000000000000..5c80bb4b80c7 --- /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 +#include + +class SkMatrix; +class SkPaint; +struct SkISize; + +sk_sp SkImage_Picture::Make(sk_sp picture, const SkISize& dimensions, + const SkMatrix* matrix, const SkPaint* paint, + SkImages::BitDepth bitDepth, sk_sp 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(&validator) : nullptr; +} + +SkPictureImageGenerator* SkImage_Picture::gen() const { + return static_cast(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 000000000000..cb2eefec98d8 --- /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 Make(sk_sp picture, const SkISize& dimensions, + const SkMatrix* matrix, const SkPaint* paint, + SkImages::BitDepth bitDepth, sk_sp 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/core/SkPictureImageGenerator.cpp b/src/image/SkPictureImageGenerator.cpp similarity index 56% rename from src/core/SkPictureImageGenerator.cpp rename to src/image/SkPictureImageGenerator.cpp index 4177cbf77e04..864fad91396c 100644 --- a/src/core/SkPictureImageGenerator.cpp +++ b/src/image/SkPictureImageGenerator.cpp @@ -5,57 +5,24 @@ * 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/SkSurface.h" +#include "include/core/SkSize.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, 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 onMakeTextureImage(skgpu::graphite::Recorder*, - const SkImageInfo&, - skgpu::Mipmapped) override; -#endif - -private: - sk_sp fPicture; - SkMatrix fMatrix; - SkTLazy fPaint; - SkSurfaceProps fProps; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// +#include +#include namespace SkImageGenerators { std::unique_ptr MakeFromPicture( @@ -96,7 +63,7 @@ std::unique_ptr MakeFromPicture(const SkISize& size, SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp picture, const SkMatrix* matrix, const SkPaint* paint, const SkSurfaceProps& props) - : BASE_CLASS(info) + : SkImageGenerator(info) , fPicture(std::move(picture)) , fProps(props) { @@ -122,47 +89,11 @@ bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, 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 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 "include/core/SkSurface.h" #include "src/gpu/graphite/Log.h" sk_sp SkPictureImageGenerator::onMakeTextureImage(skgpu::graphite::Recorder* recorder, diff --git a/src/image/SkPictureImageGenerator.h b/src/image/SkPictureImageGenerator.h new file mode 100644 index 000000000000..6f5e7c0be92e --- /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 + +struct SkImageInfo; + +class SkPictureImageGenerator : public SkImageGenerator { +public: + SkPictureImageGenerator(const SkImageInfo&, sk_sp, 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 onMakeTextureImage(skgpu::graphite::Recorder*, + const SkImageInfo&, + skgpu::Mipmapped) override; +#endif + +private: + sk_sp fPicture; + SkMatrix fMatrix; + SkTLazy fPaint; + SkSurfaceProps fProps; + + friend class SkImage_Picture; +}; + +#endif