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#ifndef GrTextureProducer_DEFINED
9#define GrTextureProducer_DEFINED
10
11#include "include/core/SkImageInfo.h"
12#include "include/private/GrResourceKey.h"
13#include "include/private/SkNoncopyable.h"
14#include "src/gpu/GrImageInfo.h"
15#include "src/gpu/GrSamplerState.h"
16
17class GrFragmentProcessor;
18class GrRecordingContext;
19class GrTexture;
20class GrTextureProxy;
21class SkColorSpace;
22class SkMatrix;
23struct SkRect;
24
25/**
26 * Different GPUs and API extensions have different requirements with respect to what texture
27 * sampling parameters may be used with textures of various types. This class facilitates making
28 * texture compatible with a given GrSamplerState. There are two immediate subclasses defined
29 * below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
30 * SkImage). It supports subsetting the original texture. The other is for use cases where the
31 * source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
32 */
33class GrTextureProducer : public SkNoncopyable {
34public:
35 virtual ~GrTextureProducer() = default;
36
37 /**
38 * Helper for creating a fragment processor to sample the texture with a given filtering mode.
39 * Attempts to avoid unnecessary copies (e.g. for planar sources or subsets) by generating more
40 * complex shader code.
41 *
42 * @param textureMatrix Matrix used to access the texture. It is applied to
43 * the local coords. The post-transformed coords should
44 * be in texel units (rather than normalized) with
45 * respect to this Producer's bounds (width()/height()).
46 * @param subset If not null, a subset of the texture to restrict
47 * sampling to. The wrap modes apply to this subset.
48 * @param domain If not null, a known limit on the texture coordinates
49 * that will be accessed. Applies after textureMatrix.
50 * @param sampler Sampler state. Wrap modes applies to subset if not
51 * null, otherwise to the entire source.
52 **/
53 virtual std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
54 const SkMatrix& textureMatrix,
55 const SkRect* subset,
56 const SkRect* domain,
57 GrSamplerState sampler) = 0;
58
59 /**
60 * Similar createFragmentProcessor but produces a fragment processor that does bicubic
61 * interpolation of the source. Attempts to avoid unnecessary copies (e.g. for planar sources or
62 * subsets) by generating more complex shader code.
63 *
64 * @param textureMatrix Matrix used to access the texture. It is applied to
65 * the local coords. The post-transformed coords should
66 * be in texel units (rather than normalized) with
67 * respect to this Producer's bounds (width()/height()).
68 * @param subset If not null, a subset of the texture to restrict
69 * sampling to. The wrap modes apply to this subset.
70 * @param domain If not null, a known limit on the texture coordinates
71 * that will be accessed. Applies after textureMatrix.
72 * @param wrapX Wrap mode on x axis. Applied to subset if not null,
73 * otherwise to the entire source.
74 * @param wrapY Wrap mode on y axis. Applied to subset if not null,
75 * otherwise to the entire source.
76 */
77 virtual std::unique_ptr<GrFragmentProcessor> createBicubicFragmentProcessor(
78 const SkMatrix& textureMatrix,
79 const SkRect* subset,
80 const SkRect* domain,
81 GrSamplerState::WrapMode wrapX,
82 GrSamplerState::WrapMode wrapY) = 0;
83
84 /**
85 * Returns a texture view, possibly with MIP maps. The request for MIP maps may not be honored
86 * base on caps, format, and whether the texture is 1x1. A non-MIP mapped request may still
87 * receive a MIP mapped texture (if that is what is available in the cache).
88 */
89 GrSurfaceProxyView view(GrMipmapped);
90
91 int width() const { return fImageInfo.width(); }
92 int height() const { return fImageInfo.height(); }
93 SkISize dimensions() const { return fImageInfo.dimensions(); }
94 GrColorType colorType() const { return fImageInfo.colorType(); }
95 SkAlphaType alphaType() const { return fImageInfo.alphaType(); }
96 SkColorSpace* colorSpace() const { return fImageInfo.colorSpace(); }
97 bool isAlphaOnly() const { return GrColorTypeIsAlphaOnly(fImageInfo.colorType()); }
98 /* Is it a planar image consisting of multiple textures that may have different resolutions? */
99 virtual bool isPlanar() const { return false; }
100
101protected:
102 GrTextureProducer(GrRecordingContext* context, const GrImageInfo& imageInfo)
103 : fContext(context), fImageInfo(imageInfo) {}
104
105 // Helper for making a texture effect from a single proxy view.
106 std::unique_ptr<GrFragmentProcessor> createFragmentProcessorForView(
107 GrSurfaceProxyView view,
108 const SkMatrix& textureMatrix,
109 const SkRect* subset,
110 const SkRect* domain,
111 GrSamplerState sampler);
112
113 // Helper for making a bicubic effect from a single proxy view.
114 std::unique_ptr<GrFragmentProcessor> createBicubicFragmentProcessorForView(
115 GrSurfaceProxyView view,
116 const SkMatrix& textureMatrix,
117 const SkRect* subset,
118 const SkRect* domain,
119 GrSamplerState::WrapMode wrapX,
120 GrSamplerState::WrapMode wrapY);
121
122 GrRecordingContext* context() const { return fContext; }
123
124private:
125 virtual GrSurfaceProxyView onView(GrMipmapped) = 0;
126
127 GrRecordingContext* fContext;
128 const GrImageInfo fImageInfo;
129
130 typedef SkNoncopyable INHERITED;
131};
132
133#endif
134