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