• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 /**************************************************************************************************
9  *** This file was autogenerated from GrConfigConversionEffect.fp; do not modify.
10  **************************************************************************************************/
11 #ifndef GrConfigConversionEffect_DEFINED
12 #define GrConfigConversionEffect_DEFINED
13 #include "include/core/SkTypes.h"
14 
15 #include "include/gpu/GrContext.h"
16 #include "src/gpu/GrClip.h"
17 #include "src/gpu/GrContextPriv.h"
18 #include "src/gpu/GrProxyProvider.h"
19 #include "src/gpu/GrRenderTargetContext.h"
20 
21 #include "src/gpu/GrCoordTransform.h"
22 #include "src/gpu/GrFragmentProcessor.h"
23 class GrConfigConversionEffect : public GrFragmentProcessor {
24 public:
TestForPreservingPMConversions(GrContext * context)25     static bool TestForPreservingPMConversions(GrContext* context) {
26         static constexpr int kSize = 256;
27         static constexpr GrColorType kColorType = GrColorType::kRGBA_8888;
28         SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
29         uint32_t* srcData = data.get();
30         uint32_t* firstRead = data.get() + kSize * kSize;
31         uint32_t* secondRead = data.get() + 2 * kSize * kSize;
32 
33         // Fill with every possible premultiplied A, color channel value. There will be 256-y
34         // duplicate values in row y. We set r, g, and b to the same value since they are handled
35         // identically.
36         for (int y = 0; y < kSize; ++y) {
37             for (int x = 0; x < kSize; ++x) {
38                 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[kSize * y + x]);
39                 color[3] = y;
40                 color[2] = SkTMin(x, y);
41                 color[1] = SkTMin(x, y);
42                 color[0] = SkTMin(x, y);
43             }
44         }
45         memset(firstRead, 0, kSize * kSize * sizeof(uint32_t));
46         memset(secondRead, 0, kSize * kSize * sizeof(uint32_t));
47 
48         const SkImageInfo ii =
49                 SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
50 
51         sk_sp<GrRenderTargetContext> readRTC(context->priv().makeDeferredRenderTargetContext(
52                 SkBackingFit::kExact, kSize, kSize, kColorType, nullptr));
53         sk_sp<GrRenderTargetContext> tempRTC(context->priv().makeDeferredRenderTargetContext(
54                 SkBackingFit::kExact, kSize, kSize, kColorType, nullptr));
55         if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
56             return false;
57         }
58         // Adding discard to appease vulkan validation warning about loading uninitialized data on
59         // draw
60         readRTC->discard();
61 
62         GrProxyProvider* proxyProvider = context->priv().proxyProvider();
63 
64         SkPixmap pixmap(ii, srcData, 4 * kSize);
65 
66         // This function is only ever called if we are in a GrContext that has a GrGpu since we are
67         // calling read pixels here. Thus the pixel data will be uploaded immediately and we don't
68         // need to keep the pixel data alive in the proxy. Therefore the ReleaseProc is nullptr.
69         sk_sp<SkImage> image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
70 
71         sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(
72                 std::move(image), 1, SkBudgeted::kYes, SkBackingFit::kExact);
73         if (!dataProxy) {
74             return false;
75         }
76 
77         static const SkRect kRect = SkRect::MakeIWH(kSize, kSize);
78 
79         // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
80         // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
81         // We then verify that two reads produced the same values.
82 
83         GrPaint paint1;
84         GrPaint paint2;
85         GrPaint paint3;
86         std::unique_ptr<GrFragmentProcessor> pmToUPM(
87                 new GrConfigConversionEffect(PMConversion::kToUnpremul));
88         std::unique_ptr<GrFragmentProcessor> upmToPM(
89                 new GrConfigConversionEffect(PMConversion::kToPremul));
90 
91         paint1.addColorTextureProcessor(dataProxy, SkMatrix::I());
92         paint1.addColorFragmentProcessor(pmToUPM->clone());
93         paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
94 
95         readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect,
96                                 kRect);
97         if (!readRTC->readPixels(ii, firstRead, 0, {0, 0})) {
98             return false;
99         }
100 
101         // Adding discard to appease vulkan validation warning about loading uninitialized data on
102         // draw
103         tempRTC->discard();
104 
105         paint2.addColorTextureProcessor(readRTC->asTextureProxyRef(), SkMatrix::I());
106         paint2.addColorFragmentProcessor(std::move(upmToPM));
107         paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
108 
109         tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect,
110                                 kRect);
111 
112         paint3.addColorTextureProcessor(tempRTC->asTextureProxyRef(), SkMatrix::I());
113         paint3.addColorFragmentProcessor(std::move(pmToUPM));
114         paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
115 
116         readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect,
117                                 kRect);
118 
119         if (!readRTC->readPixels(ii, secondRead, 0, {0, 0})) {
120             return false;
121         }
122 
123         for (int y = 0; y < kSize; ++y) {
124             for (int x = 0; x <= y; ++x) {
125                 if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) {
126                     return false;
127                 }
128             }
129         }
130 
131         return true;
132     }
133 
Make(std::unique_ptr<GrFragmentProcessor> fp,PMConversion pmConversion)134     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
135                                                      PMConversion pmConversion) {
136         if (!fp) {
137             return nullptr;
138         }
139         std::unique_ptr<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion));
140         std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {std::move(fp), std::move(ccFP)};
141         return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
142     }
143     GrConfigConversionEffect(const GrConfigConversionEffect& src);
144     std::unique_ptr<GrFragmentProcessor> clone() const override;
name()145     const char* name() const override { return "ConfigConversionEffect"; }
146     PMConversion pmConversion;
147 
148 private:
GrConfigConversionEffect(PMConversion pmConversion)149     GrConfigConversionEffect(PMConversion pmConversion)
150             : INHERITED(kGrConfigConversionEffect_ClassID, kNone_OptimizationFlags)
151             , pmConversion(pmConversion) {}
152     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
153     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
154     bool onIsEqual(const GrFragmentProcessor&) const override;
155     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
156     typedef GrFragmentProcessor INHERITED;
157 };
158 #endif
159