• 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/SkImageGenerator.h"
10 #include "include/core/SkMatrix.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPicture.h"
13 #include "include/core/SkSurface.h"
14 #include "src/core/SkTLazy.h"
15 #include "src/image/SkImage_Base.h"
16 
17 class SkPictureImageGenerator : public SkImageGenerator {
18 public:
19     SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture>, const SkMatrix*,
20                             const SkPaint*);
21 
22 protected:
23     bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts)
24         override;
25 
26 #if SK_SUPPORT_GPU
27     GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
28                                          GrMipmapped, GrImageTexGenPolicy) override;
29 #endif
30 
31 private:
32     sk_sp<SkPicture>    fPicture;
33     SkMatrix            fMatrix;
34     SkTLazy<SkPaint>    fPaint;
35 
36     using INHERITED = SkImageGenerator;
37 };
38 
39 ///////////////////////////////////////////////////////////////////////////////////////////////////
40 
41 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)42 SkImageGenerator::MakeFromPicture(const SkISize& size, sk_sp<SkPicture> picture,
43                                   const SkMatrix* matrix, const SkPaint* paint,
44                                   SkImage::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace) {
45     if (!picture || !colorSpace || size.isEmpty()) {
46         return nullptr;
47     }
48 
49     SkColorType colorType = kN32_SkColorType;
50     if (SkImage::BitDepth::kF16 == bitDepth) {
51         colorType = kRGBA_F16_SkColorType;
52     }
53 
54     SkImageInfo info =
55             SkImageInfo::Make(size, colorType, kPremul_SkAlphaType, std::move(colorSpace));
56     return std::unique_ptr<SkImageGenerator>(
57         new SkPictureImageGenerator(info, std::move(picture), matrix, paint));
58 }
59 
60 ///////////////////////////////////////////////////////////////////////////////////////////////////
61 
SkPictureImageGenerator(const SkImageInfo & info,sk_sp<SkPicture> picture,const SkMatrix * matrix,const SkPaint * paint)62 SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
63                                                  const SkMatrix* matrix, const SkPaint* paint)
64     : INHERITED(info)
65     , fPicture(std::move(picture)) {
66 
67     if (matrix) {
68         fMatrix = *matrix;
69     } else {
70         fMatrix.reset();
71     }
72 
73     if (paint) {
74         fPaint.set(*paint);
75     }
76 }
77 
onGetPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const Options & opts)78 bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
79                                           const Options& opts) {
80     SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
81     std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, pixels, rowBytes, &props);
82     if (!canvas) {
83         return false;
84     }
85     canvas->clear(0);
86     canvas->drawPicture(fPicture, &fMatrix, fPaint.getMaybeNull());
87     return true;
88 }
89 
90 ///////////////////////////////////////////////////////////////////////////////////////////////////
91 
92 #if SK_SUPPORT_GPU
93 #include "include/gpu/GrRecordingContext.h"
94 #include "src/gpu/GrRecordingContextPriv.h"
95 #include "src/gpu/SkGr.h"
96 
onGenerateTexture(GrRecordingContext * ctx,const SkImageInfo & info,const SkIPoint & origin,GrMipmapped mipmapped,GrImageTexGenPolicy texGenPolicy)97 GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
98                                                               const SkImageInfo& info,
99                                                               const SkIPoint& origin,
100                                                               GrMipmapped mipmapped,
101                                                               GrImageTexGenPolicy texGenPolicy) {
102     SkASSERT(ctx);
103 
104     SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
105 
106     SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
107                                   ? SkBudgeted::kNo
108                                   : SkBudgeted::kYes;
109     auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
110                                                &props, mipmapped == GrMipmapped::kYes);
111     if (!surface) {
112         return {};
113     }
114 
115     SkMatrix matrix = fMatrix;
116     matrix.postTranslate(-origin.x(), -origin.y());
117     surface->getCanvas()->clear(0);
118     surface->getCanvas()->drawPicture(fPicture.get(), &matrix, fPaint.getMaybeNull());
119     sk_sp<SkImage> image(surface->makeImageSnapshot());
120     if (!image) {
121         return {};
122     }
123     auto [view, ct] = as_IB(image)->asView(ctx, mipmapped);
124     SkASSERT(view);
125     SkASSERT(mipmapped == GrMipmapped::kNo ||
126              view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
127     return view;
128 }
129 #endif
130