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