• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkColorSpace.h"
10 #include "include/core/SkImageGenerator.h"
11 #include "include/core/SkMatrix.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPicture.h"
14 #include "include/core/SkSurface.h"
15 #include "src/base/SkTLazy.h"
16 #include "src/image/SkImage_Base.h"
17 
18 #if defined(SK_GANESH)
19 #include "src/gpu/ganesh/GrTextureProxy.h"
20 #endif
21 
22 class SkPictureImageGenerator : public SkImageGenerator {
23 public:
24     SkPictureImageGenerator(const SkImageInfo&, sk_sp<SkPicture>, const SkMatrix*,
25                             const SkPaint*, const SkSurfaceProps&);
26 
27 protected:
28     bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&) override;
29 
30 #if defined(SK_GANESH)
31     GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,
32                                          GrMipmapped, GrImageTexGenPolicy) override;
33 #endif
34 
35 #if SK_GRAPHITE
36     sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*,
37                                       const SkImageInfo&,
38                                       skgpu::Mipmapped) override;
39 #endif
40 
41 private:
42     sk_sp<SkPicture> fPicture;
43     SkMatrix         fMatrix;
44     SkTLazy<SkPaint> fPaint;
45     SkSurfaceProps   fProps;
46 
47     using INHERITED = SkImageGenerator;
48 };
49 
50 ///////////////////////////////////////////////////////////////////////////////////////////////////
51 
52 std::unique_ptr<SkImageGenerator>
MakeFromPicture(const SkISize & size,sk_sp<SkPicture> picture,const SkMatrix * matrix,const SkPaint * paint,SkImage::BitDepth bitDepth,sk_sp<SkColorSpace> colorSpace,SkSurfaceProps props)53 SkImageGenerator::MakeFromPicture(const SkISize& size, sk_sp<SkPicture> picture,
54                                   const SkMatrix* matrix, const SkPaint* paint,
55                                   SkImage::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace,
56                                   SkSurfaceProps props) {
57     if (!picture || !colorSpace || size.isEmpty()) {
58         return nullptr;
59     }
60 
61     SkColorType colorType = kN32_SkColorType;
62     if (SkImage::BitDepth::kF16 == bitDepth) {
63         colorType = kRGBA_F16_SkColorType;
64     }
65 
66     SkImageInfo info =
67             SkImageInfo::Make(size, colorType, kPremul_SkAlphaType, std::move(colorSpace));
68     return std::unique_ptr<SkImageGenerator>(
69         new SkPictureImageGenerator(info, std::move(picture), matrix, paint, props));
70 }
71 
72 ///////////////////////////////////////////////////////////////////////////////////////////////////
73 
SkPictureImageGenerator(const SkImageInfo & info,sk_sp<SkPicture> picture,const SkMatrix * matrix,const SkPaint * paint,const SkSurfaceProps & props)74 SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
75                                                  const SkMatrix* matrix, const SkPaint* paint,
76                                                  const SkSurfaceProps& props)
77         : SkImageGenerator(info)
78         , fPicture(std::move(picture))
79         , fProps(props) {
80 
81     if (matrix) {
82         fMatrix = *matrix;
83     } else {
84         fMatrix.reset();
85     }
86 
87     if (paint) {
88         fPaint.set(*paint);
89     }
90 }
91 
onGetPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const Options & opts)92 bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
93                                           const Options& opts) {
94     std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &fProps);
95     if (!canvas) {
96         return false;
97     }
98     canvas->clear(0);
99     canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
100     return true;
101 }
102 
103 ///////////////////////////////////////////////////////////////////////////////////////////////////
104 
105 #if defined(SK_GANESH)
106 #include "include/gpu/GrRecordingContext.h"
107 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
108 #include "src/gpu/ganesh/SkGr.h"
109 
onGenerateTexture(GrRecordingContext * ctx,const SkImageInfo & info,GrMipmapped mipmapped,GrImageTexGenPolicy texGenPolicy)110 GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
111                                                               const SkImageInfo& info,
112                                                               GrMipmapped mipmapped,
113                                                               GrImageTexGenPolicy texGenPolicy) {
114     SkASSERT(ctx);
115 
116     skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
117                                        ? skgpu::Budgeted::kNo
118                                        : skgpu::Budgeted::kYes;
119     auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
120                                                &fProps, mipmapped == GrMipmapped::kYes);
121     if (!surface) {
122         return {};
123     }
124 
125     surface->getCanvas()->clear(SkColors::kTransparent);
126     surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
127     sk_sp<SkImage> image(surface->makeImageSnapshot());
128     if (!image) {
129         return {};
130     }
131     auto [view, ct] = as_IB(image)->asView(ctx, mipmapped);
132     SkASSERT(view);
133     SkASSERT(mipmapped == GrMipmapped::kNo ||
134              view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
135     return view;
136 }
137 
138 #endif // defined(SK_GANESH)
139 
140 ///////////////////////////////////////////////////////////////////////////////////////////////////
141 
142 #if SK_GRAPHITE
143 #include "src/gpu/graphite/Log.h"
144 
onMakeTextureImage(skgpu::graphite::Recorder * recorder,const SkImageInfo & info,skgpu::Mipmapped mipmapped)145 sk_sp<SkImage> SkPictureImageGenerator::onMakeTextureImage(skgpu::graphite::Recorder* recorder,
146                                                            const SkImageInfo& info,
147                                                            skgpu::Mipmapped mipmapped) {
148     using namespace skgpu::graphite;
149 
150     sk_sp<SkSurface> surface = SkSurface::MakeGraphite(recorder, info, mipmapped);
151     if (!surface) {
152         SKGPU_LOG_E("Failed to create Surface");
153         return nullptr;
154     }
155 
156     surface->getCanvas()->clear(SkColors::kTransparent);
157     surface->getCanvas()->drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
158     return surface->asImage();
159 }
160 
161 #endif // SK_GRAPHITE
162