• 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 "SkImage_Base.h"
9 #include "SkCanvas.h"
10 #include "SkMakeUnique.h"
11 #include "SkMatrix.h"
12 #include "SkPaint.h"
13 #include "SkPicture.h"
14 #include "SkPictureImageGenerator.h"
15 #include "SkSurface.h"
16 
17 std::unique_ptr<SkImageGenerator>
Make(const SkISize & size,sk_sp<SkPicture> picture,const SkMatrix * matrix,const SkPaint * paint,SkImage::BitDepth bitDepth,sk_sp<SkColorSpace> colorSpace)18 SkPictureImageGenerator::Make(const SkISize& size, sk_sp<SkPicture> picture, const SkMatrix* matrix,
19                               const SkPaint* paint, SkImage::BitDepth bitDepth,
20                               sk_sp<SkColorSpace> colorSpace) {
21     if (!picture || size.isEmpty()) {
22         return nullptr;
23     }
24 
25     if (SkImage::BitDepth::kF16 == bitDepth && (!colorSpace || !colorSpace->gammaIsLinear())) {
26         return nullptr;
27     }
28 
29     if (colorSpace && (!colorSpace->gammaCloseToSRGB() && !colorSpace->gammaIsLinear())) {
30         return nullptr;
31     }
32 
33     SkColorType colorType = kN32_SkColorType;
34     if (SkImage::BitDepth::kF16 == bitDepth) {
35         colorType = kRGBA_F16_SkColorType;
36     }
37 
38     SkImageInfo info = SkImageInfo::Make(size.width(), size.height(), colorType,
39                                          kPremul_SkAlphaType, std::move(colorSpace));
40     return std::unique_ptr<SkImageGenerator>(
41                              new SkPictureImageGenerator(info, std::move(picture), matrix, paint));
42 }
43 
SkPictureImageGenerator(const SkImageInfo & info,sk_sp<SkPicture> picture,const SkMatrix * matrix,const SkPaint * paint)44 SkPictureImageGenerator::SkPictureImageGenerator(const SkImageInfo& info, sk_sp<SkPicture> picture,
45                                                  const SkMatrix* matrix, const SkPaint* paint)
46     : INHERITED(info)
47     , fPicture(std::move(picture)) {
48 
49     if (matrix) {
50         fMatrix = *matrix;
51     } else {
52         fMatrix.reset();
53     }
54 
55     if (paint) {
56         fPaint.set(*paint);
57     }
58 }
59 
onGetPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,SkPMColor ctable[],int * ctableCount)60 bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
61                                           SkPMColor ctable[], int* ctableCount) {
62     if (ctable || ctableCount) {
63         return false;
64     }
65 
66     SkBitmap bitmap;
67     if (!bitmap.installPixels(info, pixels, rowBytes)) {
68         return false;
69     }
70 
71     bitmap.eraseColor(SK_ColorTRANSPARENT);
72     SkCanvas canvas(bitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
73     canvas.drawPicture(fPicture.get(), &fMatrix, fPaint.getMaybeNull());
74 
75     return true;
76 }
77 
78 ///////////////////////////////////////////////////////////////////////////////////////////////////
79 
80 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)81 SkImageGenerator::MakeFromPicture(const SkISize& size, sk_sp<SkPicture> picture,
82                                   const SkMatrix* matrix, const SkPaint* paint,
83                                   SkImage::BitDepth bitDepth, sk_sp<SkColorSpace> colorSpace) {
84     // Check this here (rather than in SkPictureImageGenerator::Create) so SkPictureShader
85     // has a private entry point to create legacy picture backed images.
86     if (!colorSpace) {
87         return nullptr;
88     }
89 
90     return SkPictureImageGenerator::Make(size, std::move(picture), matrix, paint, bitDepth,
91                                          std::move(colorSpace));
92 }
93 
94 ///////////////////////////////////////////////////////////////////////////////////////////////////
95 
96 #if SK_SUPPORT_GPU
onGenerateTexture(GrContext * ctx,const SkImageInfo & info,const SkIPoint & origin)97 sk_sp<GrTextureProxy> SkPictureImageGenerator::onGenerateTexture(GrContext* ctx,
98                                                                  const SkImageInfo& info,
99                                                                  const SkIPoint& origin) {
100     SkASSERT(ctx);
101 
102     //
103     // TODO: respect the usage, by possibly creating a different (pow2) surface
104     //
105     sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kYes, info));
106     if (!surface) {
107         return nullptr;
108     }
109 
110     SkMatrix matrix = fMatrix;
111     matrix.postTranslate(-origin.x(), -origin.y());
112     surface->getCanvas()->clear(0); // does NewRenderTarget promise to do this for us?
113     surface->getCanvas()->drawPicture(fPicture.get(), &matrix, fPaint.getMaybeNull());
114     sk_sp<SkImage> image(surface->makeImageSnapshot());
115     if (!image) {
116         return nullptr;
117     }
118     return as_IB(image)->asTextureProxyRef();
119 }
120 #endif
121