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