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 */
18enum 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
25GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrProcessor(classID) {}
26
27const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::textureSampler(int i) const {
28 SkASSERT(i >= 0 && i < this->numTextureSamplers());
29 return this->onTextureSampler(i);
30}
31
32uint32_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
60static 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
68GrPrimitiveProcessor::TextureSampler::TextureSampler(GrSamplerState samplerState,
69 const GrBackendFormat& backendFormat,
70 const GrSwizzle& swizzle) {
71 this->reset(samplerState, backendFormat, swizzle);
72}
73
74void 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