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(GrRecordingContext* 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* subset,
64 const SkRect* domain,
65 GrSamplerState samplerState) {
66 // Check whether it's already been flattened.
67 if (fImage->fRGBView.proxy()) {
68 return this->INHERITED::createFragmentProcessor(textureMatrix, subset, domain,
69 samplerState);
70 }
71
72 // Check to see if the client has given us pre-mipped textures or we can generate them
73 // If not disable mip mapping. Also disable when a subset is requested.
74 if (samplerState.mipmapped() == GrMipmapped::kYes &&
75 (subset || !fImage->setupMipmapsForPlanes(this->context()))) {
76 samplerState.setMipmapMode(GrSamplerState::MipmapMode::kNone);
77 }
78
79 const auto& caps = *fImage->context()->priv().caps();
80 auto fp = GrYUVtoRGBEffect::Make(fImage->fViews, fImage->fYUVAIndices, fImage->fYUVColorSpace,
81 samplerState, caps, textureMatrix, subset, domain);
82 if (fImage->fFromColorSpace) {
83 fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(),
84 fImage->alphaType(), fImage->colorSpace(),
85 kPremul_SkAlphaType);
86 }
87 return fp;
88}
89
90std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createBicubicFragmentProcessor(
91 const SkMatrix& textureMatrix,
92 const SkRect* subset,
93 const SkRect* domain,
94 GrSamplerState::WrapMode wrapX,
95 GrSamplerState::WrapMode wrapY) {
96 const auto& caps = *fImage->context()->priv().caps();
97 GrSamplerState samplerState(wrapX, wrapY, GrSamplerState::Filter::kNearest);
98 auto fp = GrYUVtoRGBEffect::Make(fImage->fViews, fImage->fYUVAIndices, fImage->fYUVColorSpace,
99 samplerState, caps, SkMatrix::I(), subset, domain);
100 fp = GrBicubicEffect::Make(std::move(fp),
101 fImage->alphaType(),
102 textureMatrix,
103 GrBicubicEffect::Kernel::kMitchell,
104 GrBicubicEffect::Direction::kXY);
105 if (fImage->fFromColorSpace) {
106 fp = GrColorSpaceXformEffect::Make(std::move(fp),
107 fImage->fFromColorSpace.get(), fImage->alphaType(),
108 fImage->colorSpace(), kPremul_SkAlphaType);
109 }
110 return fp;
111}
112