/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/GrImageTextureMaker.h" #include "src/gpu/GrColorSpaceXform.h" #include "src/gpu/SkGr.h" #include "src/gpu/effects/GrYUVtoRGBEffect.h" #include "src/image/SkImage_GpuYUVA.h" #include "src/image/SkImage_Lazy.h" static GrColorSpaceInfo make_info(const SkImage*& image) { return GrColorSpaceInfo(SkColorTypeToGrColorType(image->colorType()), image->alphaType(), image->refColorSpace()); } GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client, SkImage::CachingHint chint, bool useDecal) : INHERITED(context, client->width(), client->height(), make_info(client), useDecal) , fImage(static_cast(client)) , fCachingHint(chint) { SkASSERT(client->isLazyGenerated()); GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(), SkIRect::MakeWH(this->width(), this->height())); } sk_sp GrImageTextureMaker::refOriginalTextureProxy(bool willBeMipped, AllowedTexGenType onlyIfFast) { return fImage->lockTextureProxy(this->context(), fOriginalKey, fCachingHint, willBeMipped, onlyIfFast); } void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) { if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) { GrUniqueKey cacheKey; fImage->makeCacheKeyFromOrigKey(fOriginalKey, &cacheKey); MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey); } } ///////////////////////////////////////////////////////////////////////////////////////////////// GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client, bool useDecal) : INHERITED(context, client->width(), client->height(), make_info(client), useDecal) , fImage(static_cast(client)) { SkASSERT(as_IB(client)->isYUVA()); GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(), SkIRect::MakeWH(this->width(), this->height())); } sk_sp GrYUVAImageTextureMaker::refOriginalTextureProxy(bool willBeMipped, AllowedTexGenType onlyIfFast) { if (AllowedTexGenType::kCheap == onlyIfFast) { return nullptr; } if (willBeMipped) { return fImage->asMippedTextureProxyRef(this->context()); } else { return fImage->asTextureProxyRef(this->context()); } } void GrYUVAImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) { // TODO: Do we ever want to disable caching? if (fOriginalKey.isValid()) { GrUniqueKey cacheKey; static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey::Builder builder(&cacheKey, fOriginalKey, kDomain, 0, "Image"); MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey); } } std::unique_ptr GrYUVAImageTextureMaker::createFragmentProcessor( const SkMatrix& textureMatrix, const SkRect& constraintRect, FilterConstraint filterConstraint, bool coordsLimitedToConstraintRect, const GrSamplerState::Filter* filterOrNullForBicubic) { // Check simple cases to see if we need to fall back to flattening the image (or whether it's // already been flattened.) if (!filterOrNullForBicubic || this->domainNeedsDecal() || fImage->fRGBProxy) { return this->INHERITED::createFragmentProcessor(textureMatrix, constraintRect, filterConstraint, coordsLimitedToConstraintRect, filterOrNullForBicubic); } // Check to see if the client has given us pre-mipped textures or we can generate them // If not, fall back to bilerp. Also fall back to bilerp when a domain is requested GrSamplerState::Filter filter = *filterOrNullForBicubic; if (GrSamplerState::Filter::kMipMap == filter && (filterConstraint == GrTextureProducer::kYes_FilterConstraint || !fImage->setupMipmapsForPlanes(this->context()))) { filter = GrSamplerState::Filter::kBilerp; } // Cannot rely on GrTextureProducer's domain infrastructure since we need to calculate domain's // per plane, which may be different, so respect the filterConstraint without any additional // analysis. const SkRect* domain = nullptr; if (filterConstraint == GrTextureProducer::kYes_FilterConstraint) { domain = &constraintRect; } auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices, fImage->fYUVColorSpace, filter, textureMatrix, domain); if (fImage->fFromColorSpace) { fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(), fImage->alphaType(), fImage->colorSpace()); } return fp; }