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 "src/gpu/GrImageTextureMaker.h"
9
10#include "src/gpu/GrColorSpaceXform.h"
11#include "src/gpu/GrContextPriv.h"
12#include "src/gpu/GrRecordingContextPriv.h"
13#include "src/gpu/SkGr.h"
14#include "src/gpu/effects/GrBicubicEffect.h"
15#include "src/gpu/effects/GrYUVtoRGBEffect.h"
16#include "src/image/SkImage_GpuYUVA.h"
17#include "src/image/SkImage_Lazy.h"
18
19static GrImageInfo get_image_info(GrRecordingContext* context, const SkImage* client) {
20 SkASSERT(client->isLazyGenerated());
21 const SkImage_Lazy* lazyImage = static_cast<const SkImage_Lazy*>(client);
22
23 GrColorType ct = lazyImage->colorTypeOfLockTextureProxy(context->priv().caps());
24
25 return {ct, client->alphaType(), client->refColorSpace(), client->dimensions()};
26}
27
28GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context,
29 const SkImage* client,
30 GrImageTexGenPolicy texGenPolicy)
31 : INHERITED(context, get_image_info(context, client))
32 , fImage(static_cast<const SkImage_Lazy*>(client))
33 , fTexGenPolicy(texGenPolicy) {
34 SkASSERT(client->isLazyGenerated());
35}
36
37GrSurfaceProxyView GrImageTextureMaker::refOriginalTextureProxyView(GrMipMapped mipMapped) {
38 return fImage->lockTextureProxyView(this->context(), fTexGenPolicy, mipMapped);
39}
40
41/////////////////////////////////////////////////////////////////////////////////////////////////
42
43GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client)
44 : INHERITED(context, client->imageInfo())
45 , fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
46 SkASSERT(as_IB(client)->isYUVA());
47}
48
49GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(GrMipMapped mipMapped) {
50 if (mipMapped == GrMipMapped::kYes) {
51 return fImage->refMippedView(this->context());
52 } else {
53 if (const GrSurfaceProxyView* view = fImage->view(this->context())) {
54 return *view;
55 } else {
56 return {};
57 }
58 }
59}
60
61std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor(
62 const SkMatrix& textureMatrix,
63 const SkRect& constraintRect,
64 FilterConstraint filterConstraint,
65 bool coordsLimitedToConstraintRect,
66 GrSamplerState::WrapMode wrapX,
67 GrSamplerState::WrapMode wrapY,
68 const GrSamplerState::Filter* filterOrNullForBicubic) {
69 // Check whether it's already been flattened.
70 if (fImage->fRGBView.proxy()) {
71 return this->INHERITED::createFragmentProcessor(
72 textureMatrix, constraintRect, filterConstraint, coordsLimitedToConstraintRect,
73 wrapX, wrapY, filterOrNullForBicubic);
74 }
75
76 GrSamplerState::Filter filter =
77 filterOrNullForBicubic ? *filterOrNullForBicubic : GrSamplerState::Filter::kNearest;
78
79 // Check to see if the client has given us pre-mipped textures or we can generate them
80 // If not, fall back to bilerp. Also fall back to bilerp when a domain is requested
81 if (GrSamplerState::Filter::kMipMap == filter &&
82 (filterConstraint == GrTextureProducer::kYes_FilterConstraint ||
83 !fImage->setupMipmapsForPlanes(this->context()))) {
84 filter = GrSamplerState::Filter::kBilerp;
85 }
86
87 // Cannot rely on GrTextureProducer's domain infrastructure since we need to calculate domain's
88 // per plane, which may be different, so respect the filterConstraint without any additional
89 // analysis.
90 const SkRect* domain = nullptr;
91 if (filterConstraint == GrTextureProducer::kYes_FilterConstraint) {
92 domain = &constraintRect;
93 }
94
95 const auto& caps = *fImage->context()->priv().caps();
96 const SkMatrix& m = filterOrNullForBicubic ? textureMatrix : SkMatrix::I();
97 auto fp = GrYUVtoRGBEffect::Make(fImage->fViews, fImage->fYUVAIndices, fImage->fYUVColorSpace,
98 filter, caps, m, domain);
99 if (!filterOrNullForBicubic) {
100 fp = GrBicubicEffect::Make(std::move(fp), fImage->alphaType(), textureMatrix,
101 GrBicubicEffect::Direction::kXY);
102 }
103 if (fImage->fFromColorSpace) {
104 fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(),
105 fImage->alphaType(), fImage->colorSpace());
106 }
107 return fp;
108}
109