Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 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 "GrTextureMaker.h"
      9 
     10 #include "GrContext.h"
     11 #include "GrGpu.h"
     12 #include "GrResourceProvider.h"
     13 
     14 sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerParams& params,
     15                                                                SkColorSpace* dstColorSpace,
     16                                                                sk_sp<SkColorSpace>* texColorSpace,
     17                                                                SkScalar scaleAdjust[2]) {
     18     CopyParams copyParams;
     19     bool willBeMipped = params.filterMode() == GrSamplerParams::kMipMap_FilterMode;
     20 
     21     if (!fContext->caps()->mipMapSupport()) {
     22         willBeMipped = false;
     23     }
     24 
     25     if (texColorSpace) {
     26         *texColorSpace = this->getColorSpace(dstColorSpace);
     27     }
     28 
     29     sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
     30                                                                  AllowedTexGenType::kCheap));
     31     if (original) {
     32         if (!fContext->getGpu()->isACopyNeededForTextureParams(original.get(), params, &copyParams,
     33                                                                scaleAdjust)) {
     34             return original;
     35         }
     36     } else {
     37         if (!fContext->getGpu()->isACopyNeededForTextureParams(this->width(), this->height(),
     38                                                                params, &copyParams, scaleAdjust)) {
     39             return this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
     40                                                  AllowedTexGenType::kAny);
     41         }
     42     }
     43 
     44     GrUniqueKey copyKey;
     45     this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
     46     if (copyKey.isValid()) {
     47         sk_sp<GrTextureProxy> result(fContext->resourceProvider()->findProxyByUniqueKey(copyKey));
     48         if (result) {
     49             return result;
     50         }
     51     }
     52 
     53     sk_sp<GrTextureProxy> result;
     54     if (original) {
     55         result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
     56     } else {
     57         result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace);
     58     }
     59 
     60     if (!result) {
     61         return nullptr;
     62     }
     63 
     64     if (copyKey.isValid()) {
     65         fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get());
     66         this->didCacheCopy(copyKey);
     67     }
     68     return result;
     69 }
     70 
     71 sk_sp<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
     72                                         const SkMatrix& textureMatrix,
     73                                         const SkRect& constraintRect,
     74                                         FilterConstraint filterConstraint,
     75                                         bool coordsLimitedToConstraintRect,
     76                                         const GrSamplerParams::FilterMode* filterOrNullForBicubic,
     77                                         SkColorSpace* dstColorSpace) {
     78 
     79     const GrSamplerParams::FilterMode* fmForDetermineDomain = filterOrNullForBicubic;
     80     if (filterOrNullForBicubic && GrSamplerParams::kMipMap_FilterMode == *filterOrNullForBicubic &&
     81         kYes_FilterConstraint == filterConstraint) {
     82         // TODo: Here we should force a copy restricted to the constraintRect since MIP maps will
     83         // read outside the constraint rect. However, as in the adjuster case, we aren't currently
     84         // doing that.
     85         // We instead we compute the domain as though were bilerping which is only correct if we
     86         // only sample level 0.
     87         static const GrSamplerParams::FilterMode kBilerp = GrSamplerParams::kBilerp_FilterMode;
     88         fmForDetermineDomain = &kBilerp;
     89     }
     90 
     91     GrSamplerParams params;
     92     if (filterOrNullForBicubic) {
     93         params.reset(SkShader::kClamp_TileMode, *filterOrNullForBicubic);
     94     } else {
     95         // Bicubic doesn't use filtering for it's texture accesses.
     96         params.reset(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
     97     }
     98     sk_sp<SkColorSpace> texColorSpace;
     99     SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
    100     sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(params, dstColorSpace,
    101                                                                &texColorSpace,
    102                                                                scaleAdjust));
    103     if (!proxy) {
    104         return nullptr;
    105     }
    106     SkMatrix adjustedMatrix = textureMatrix;
    107     adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
    108     SkRect domain;
    109     DomainMode domainMode =
    110         DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
    111                             proxy.get(),
    112                             nullptr, fmForDetermineDomain, &domain);
    113     SkASSERT(kTightCopy_DomainMode != domainMode);
    114     sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
    115                                                                        dstColorSpace);
    116     return CreateFragmentProcessorForDomainAndFilter(std::move(proxy),
    117                                                      std::move(colorSpaceXform),
    118                                                      adjustedMatrix, domainMode, domain,
    119                                                      filterOrNullForBicubic);
    120 }
    121 
    122 sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyParams& copyParams,
    123                                                                     bool willBeMipped,
    124                                                                     SkColorSpace* dstColorSpace) {
    125     sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
    126                                                                  AllowedTexGenType::kAny));
    127     if (!original) {
    128         return nullptr;
    129     }
    130 
    131     return CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
    132 }
    133