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 "GrColorSpaceXform.h"
      9 #include "GrImageTextureMaker.h"
     10 #include "SkGr.h"
     11 #include "SkImage_GpuYUVA.h"
     12 #include "SkImage_Lazy.h"
     13 #include "effects/GrYUVtoRGBEffect.h"
     14 
     15 GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client,
     16                                          SkImage::CachingHint chint, bool useDecal)
     17         : INHERITED(context, client->width(), client->height(), client->isAlphaOnly(), useDecal)
     18         , fImage(static_cast<const SkImage_Lazy*>(client))
     19         , fCachingHint(chint) {
     20     SkASSERT(client->isLazyGenerated());
     21     GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
     22                          SkIRect::MakeWH(this->width(), this->height()));
     23 }
     24 
     25 sk_sp<GrTextureProxy> GrImageTextureMaker::refOriginalTextureProxy(bool willBeMipped,
     26                                                                    AllowedTexGenType onlyIfFast) {
     27     return fImage->lockTextureProxy(this->context(), fOriginalKey, fCachingHint,
     28                                     willBeMipped, onlyIfFast);
     29 }
     30 
     31 void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
     32     if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) {
     33         GrUniqueKey cacheKey;
     34         fImage->makeCacheKeyFromOrigKey(fOriginalKey, &cacheKey);
     35         MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
     36     }
     37 }
     38 
     39 SkAlphaType GrImageTextureMaker::alphaType() const {
     40     return fImage->alphaType();
     41 }
     42 SkColorSpace* GrImageTextureMaker::colorSpace() const {
     43     return fImage->colorSpace();
     44 }
     45 
     46 /////////////////////////////////////////////////////////////////////////////////////////////////
     47 
     48 GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client,
     49                                                  bool useDecal)
     50     : INHERITED(context, client->width(), client->height(), client->isAlphaOnly(), useDecal)
     51     , fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
     52     SkASSERT(as_IB(client)->isYUVA());
     53     GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
     54                          SkIRect::MakeWH(this->width(), this->height()));
     55 }
     56 
     57 sk_sp<GrTextureProxy> GrYUVAImageTextureMaker::refOriginalTextureProxy(bool willBeMipped,
     58                                                                    AllowedTexGenType onlyIfFast) {
     59     if (AllowedTexGenType::kCheap == onlyIfFast) {
     60         return nullptr;
     61     }
     62 
     63     if (willBeMipped) {
     64         return fImage->asMippedTextureProxyRef(this->context());
     65     } else {
     66         return fImage->asTextureProxyRef(this->context());
     67     }
     68 }
     69 
     70 void GrYUVAImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
     71     // TODO: Do we ever want to disable caching?
     72     if (fOriginalKey.isValid()) {
     73         GrUniqueKey cacheKey;
     74         static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     75         GrUniqueKey::Builder builder(&cacheKey, fOriginalKey, kDomain, 0, "Image");
     76         MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
     77     }
     78 }
     79 
     80 SkAlphaType GrYUVAImageTextureMaker::alphaType() const {
     81     return fImage->alphaType();
     82 }
     83 SkColorSpace* GrYUVAImageTextureMaker::colorSpace() const {
     84     return fImage->colorSpace();
     85 }
     86 
     87 std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor(
     88     const SkMatrix& textureMatrix,
     89     const SkRect& constraintRect,
     90     FilterConstraint filterConstraint,
     91     bool coordsLimitedToConstraintRect,
     92     const GrSamplerState::Filter* filterOrNullForBicubic) {
     93 
     94     // Check simple cases to see if we need to fall back to flattening the image
     95     // TODO: See if we can relax this -- for example, if filterConstraint
     96     //       is kYes_FilterConstraint we still may not need a TextureDomain
     97     //       in some cases. Or allow YUVtoRGBEffect to take a wrap mode to
     98     //       handle ClampToBorder when a decal is needed.
     99     if (!textureMatrix.isIdentity() || kNo_FilterConstraint != filterConstraint ||
    100         !coordsLimitedToConstraintRect || !filterOrNullForBicubic ||
    101         this->domainNeedsDecal()) {
    102         return this->INHERITED::createFragmentProcessor(textureMatrix, constraintRect,
    103                                                         filterConstraint,
    104                                                         coordsLimitedToConstraintRect,
    105                                                         filterOrNullForBicubic);
    106     }
    107 
    108     // Check to see if the client has given us pre-mipped textures or we can generate them
    109     // If not, fall back to bilerp
    110     GrSamplerState::Filter filter = *filterOrNullForBicubic;
    111     if (GrSamplerState::Filter::kMipMap == filter &&
    112         !fImage->setupMipmapsForPlanes(this->context())) {
    113         filter = GrSamplerState::Filter::kBilerp;
    114     }
    115 
    116     auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices,
    117                                      fImage->fYUVColorSpace, filter);
    118     if (fImage->fTargetColorSpace) {
    119         fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fColorSpace.get(),
    120                                            fImage->alphaType(), fImage->fTargetColorSpace.get());
    121     }
    122     return fp;
    123 }
    124