1 | /* |
2 | * Copyright 2014 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/GrPrimitiveProcessor.h" |
9 | |
10 | #include "src/gpu/GrCoordTransform.h" |
11 | #include "src/gpu/GrFragmentProcessor.h" |
12 | |
13 | /** |
14 | * We specialize the vertex or fragment coord transform code for these matrix types. |
15 | * Some specializations are only applied when the coord transform is applied in the fragment |
16 | * shader. |
17 | */ |
18 | enum MatrixType { |
19 | kNone_MatrixType = 0, // Used only in FS for explicitly sampled FPs |
20 | kScaleTranslate_MatrixType = 1, // Used only in FS for explicitly sampled FPs |
21 | kNoPersp_MatrixType = 2, |
22 | kGeneral_MatrixType = 3, |
23 | }; |
24 | |
25 | GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrProcessor(classID) {} |
26 | |
27 | const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::textureSampler(int i) const { |
28 | SkASSERT(i >= 0 && i < this->numTextureSamplers()); |
29 | return this->onTextureSampler(i); |
30 | } |
31 | |
32 | uint32_t GrPrimitiveProcessor::computeCoordTransformsKey(const GrFragmentProcessor& fp) const { |
33 | // This is highly coupled with the code in GrGLSLGeometryProcessor::emitTransforms(). |
34 | SkASSERT(fp.numCoordTransforms() * 2 <= 32); |
35 | uint32_t totalKey = 0; |
36 | for (int t = 0; t < fp.numCoordTransforms(); ++t) { |
37 | uint32_t key = 0; |
38 | const GrCoordTransform& coordTransform = fp.coordTransform(t); |
39 | if (fp.isSampledWithExplicitCoords() && coordTransform.isNoOp()) { |
40 | key = kNone_MatrixType; |
41 | } else if (fp.isSampledWithExplicitCoords() && coordTransform.matrix().isScaleTranslate()) { |
42 | key = kScaleTranslate_MatrixType; |
43 | } else if (!coordTransform.matrix().hasPerspective()) { |
44 | key = kNoPersp_MatrixType; |
45 | } else { |
46 | // Note that we can also have homogeneous varyings as a result of a GP local matrix or |
47 | // homogeneous local coords generated by GP. We're relying on the GP to include any |
48 | // variability in those in its key. |
49 | key = kGeneral_MatrixType; |
50 | } |
51 | key <<= 2*t; |
52 | SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap |
53 | totalKey |= key; |
54 | } |
55 | return totalKey; |
56 | } |
57 | |
58 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
59 | |
60 | static inline GrSamplerState::Filter clamp_filter(GrTextureType type, |
61 | GrSamplerState::Filter requestedFilter) { |
62 | if (GrTextureTypeHasRestrictedSampling(type)) { |
63 | return std::min(requestedFilter, GrSamplerState::Filter::kBilerp); |
64 | } |
65 | return requestedFilter; |
66 | } |
67 | |
68 | GrPrimitiveProcessor::TextureSampler::TextureSampler(GrSamplerState samplerState, |
69 | const GrBackendFormat& backendFormat, |
70 | const GrSwizzle& swizzle) { |
71 | this->reset(samplerState, backendFormat, swizzle); |
72 | } |
73 | |
74 | void GrPrimitiveProcessor::TextureSampler::reset(GrSamplerState samplerState, |
75 | const GrBackendFormat& backendFormat, |
76 | const GrSwizzle& swizzle) { |
77 | fSamplerState = samplerState; |
78 | fSamplerState.setFilterMode(clamp_filter(backendFormat.textureType(), samplerState.filter())); |
79 | fBackendFormat = backendFormat; |
80 | fSwizzle = swizzle; |
81 | fIsInitialized = true; |
82 | } |
83 | |