Home | History | Annotate | Download | only in effects
      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 "SkTypes.h"
     14 #if SK_SUPPORT_GPU
     15 
     16 #include "GrClip.h"
     17 #include "GrContext.h"
     18 #include "GrContextPriv.h"
     19 #include "GrProxyProvider.h"
     20 #include "GrRenderTargetContext.h"
     21 #include "GrFragmentProcessor.h"
     22 #include "GrCoordTransform.h"
     23 class GrConfigConversionEffect : public GrFragmentProcessor {
     24 public:
     25     static bool TestForPreservingPMConversions(GrContext* context) {
     26         static constexpr int kSize = 256;
     27         static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
     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 
     46         const SkImageInfo ii =
     47                 SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
     48 
     49         sk_sp<GrRenderTargetContext> readRTC(context->makeDeferredRenderTargetContext(
     50                 SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
     51         sk_sp<GrRenderTargetContext> tempRTC(context->makeDeferredRenderTargetContext(
     52                 SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
     53         if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
     54             return false;
     55         }
     56         // Adding discard to appease vulkan validation warning about loading uninitialized data on
     57         // draw
     58         readRTC->discard();
     59 
     60         GrSurfaceDesc desc;
     61         desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     62         desc.fWidth = kSize;
     63         desc.fHeight = kSize;
     64         desc.fConfig = kConfig;
     65 
     66         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
     67 
     68         sk_sp<GrTextureProxy> dataProxy =
     69                 proxyProvider->createTextureProxy(desc, SkBudgeted::kYes, data, 0);
     70         if (!dataProxy) {
     71             return false;
     72         }
     73 
     74         static const SkRect kRect = SkRect::MakeIWH(kSize, kSize);
     75 
     76         // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
     77         // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
     78         // We then verify that two reads produced the same values.
     79 
     80         GrPaint paint1;
     81         GrPaint paint2;
     82         GrPaint paint3;
     83         std::unique_ptr<GrFragmentProcessor> pmToUPM(
     84                 new GrConfigConversionEffect(PMConversion::kToUnpremul));
     85         std::unique_ptr<GrFragmentProcessor> upmToPM(
     86                 new GrConfigConversionEffect(PMConversion::kToPremul));
     87 
     88         paint1.addColorTextureProcessor(dataProxy, SkMatrix::I());
     89         paint1.addColorFragmentProcessor(pmToUPM->clone());
     90         paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
     91 
     92         readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect,
     93                                 kRect);
     94         if (!readRTC->readPixels(ii, firstRead, 0, 0, 0)) {
     95             return false;
     96         }
     97 
     98         // Adding discard to appease vulkan validation warning about loading uninitialized data on
     99         // draw
    100         tempRTC->discard();
    101 
    102         paint2.addColorTextureProcessor(readRTC->asTextureProxyRef(), SkMatrix::I());
    103         paint2.addColorFragmentProcessor(std::move(upmToPM));
    104         paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
    105 
    106         tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect,
    107                                 kRect);
    108 
    109         paint3.addColorTextureProcessor(tempRTC->asTextureProxyRef(), SkMatrix::I());
    110         paint3.addColorFragmentProcessor(std::move(pmToUPM));
    111         paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
    112 
    113         readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect,
    114                                 kRect);
    115 
    116         if (!readRTC->readPixels(ii, secondRead, 0, 0, 0)) {
    117             return false;
    118         }
    119 
    120         for (int y = 0; y < kSize; ++y) {
    121             for (int x = 0; x <= y; ++x) {
    122                 if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) {
    123                     return false;
    124                 }
    125             }
    126         }
    127 
    128         return true;
    129     }
    130     PMConversion pmConversion() const { return fPmConversion; }
    131 
    132     static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
    133                                                      PMConversion pmConversion) {
    134         if (!fp) {
    135             return nullptr;
    136         }
    137         std::unique_ptr<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion));
    138         std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {std::move(fp), std::move(ccFP)};
    139         return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
    140     }
    141     GrConfigConversionEffect(const GrConfigConversionEffect& src);
    142     std::unique_ptr<GrFragmentProcessor> clone() const override;
    143     const char* name() const override { return "ConfigConversionEffect"; }
    144 
    145 private:
    146     GrConfigConversionEffect(PMConversion pmConversion)
    147             : INHERITED(kGrConfigConversionEffect_ClassID, kNone_OptimizationFlags)
    148             , fPmConversion(pmConversion) {}
    149     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
    150     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
    151     bool onIsEqual(const GrFragmentProcessor&) const override;
    152     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    153     PMConversion fPmConversion;
    154     typedef GrFragmentProcessor INHERITED;
    155 };
    156 #endif
    157 #endif
    158