117168df7798d0d12684f18df0556dc19e65b32e6bsalomon/*
217168df7798d0d12684f18df0556dc19e65b32e6bsalomon * Copyright 2014 Google Inc.
317168df7798d0d12684f18df0556dc19e65b32e6bsalomon *
417168df7798d0d12684f18df0556dc19e65b32e6bsalomon * Use of this source code is governed by a BSD-style license that can be
517168df7798d0d12684f18df0556dc19e65b32e6bsalomon * found in the LICENSE file.
617168df7798d0d12684f18df0556dc19e65b32e6bsalomon */
717168df7798d0d12684f18df0556dc19e65b32e6bsalomon
817168df7798d0d12684f18df0556dc19e65b32e6bsalomon#include "GrCoordTransform.h"
9eb1cb5c5b50febad115d859faca91d2d6af3fff2bsalomon#include "GrCaps.h"
1017168df7798d0d12684f18df0556dc19e65b32e6bsalomon#include "GrContext.h"
1117168df7798d0d12684f18df0556dc19e65b32e6bsalomon#include "GrGpu.h"
12296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips#include "GrResourceProvider.h"
13bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips#include "GrTextureProxy.h"
1417168df7798d0d12684f18df0556dc19e65b32e6bsalomon
15bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillipsstatic GrSLPrecision compute_precision(const GrShaderCaps* caps,
16bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                                       int width, int height,
17bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                                       GrSamplerParams::FilterMode filter) {
1817168df7798d0d12684f18df0556dc19e65b32e6bsalomon    // Always start at kDefault. Then if precisions differ we see if the precision needs to be
1917168df7798d0d12684f18df0556dc19e65b32e6bsalomon    // increased. Our rule is that we want at least 4 subpixel values in the representation for
209f876a37d8b80ef04ccbc7755cf4572aecc33981bsalomon    // coords between 0 to 1 when bi- or tri-lerping and 1 value when nearest filtering. Note that
219f876a37d8b80ef04ccbc7755cf4572aecc33981bsalomon    // this still might not be enough when drawing with repeat or mirror-repeat modes but that case
229f876a37d8b80ef04ccbc7755cf4572aecc33981bsalomon    // can be arbitrarily bad.
23514baff8be7f71111aa7bfb9b099a096b31e16ecBrian Salomon    int subPixelThresh = filter > GrSamplerParams::kNone_FilterMode ? 4 : 1;
24bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    GrSLPrecision precision = kDefault_GrSLPrecision;
25bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    if (caps) {
2617168df7798d0d12684f18df0556dc19e65b32e6bsalomon        if (caps->floatPrecisionVaries()) {
27bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips            int maxD = SkTMax(width, height);
28e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth            const GrShaderCaps::PrecisionInfo* info;
29bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips            info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, precision);
3017168df7798d0d12684f18df0556dc19e65b32e6bsalomon            do {
3117168df7798d0d12684f18df0556dc19e65b32e6bsalomon                SkASSERT(info->supported());
3217168df7798d0d12684f18df0556dc19e65b32e6bsalomon                // Make sure there is at least 2 bits of subpixel precision in the range of
3317168df7798d0d12684f18df0556dc19e65b32e6bsalomon                // texture coords from 0.5 to 1.0.
349f876a37d8b80ef04ccbc7755cf4572aecc33981bsalomon                if ((2 << info->fBits) / maxD > subPixelThresh) {
3517168df7798d0d12684f18df0556dc19e65b32e6bsalomon                    break;
3617168df7798d0d12684f18df0556dc19e65b32e6bsalomon                }
37bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                if (kHigh_GrSLPrecision == precision) {
3817168df7798d0d12684f18df0556dc19e65b32e6bsalomon                    break;
3917168df7798d0d12684f18df0556dc19e65b32e6bsalomon                }
40bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                GrSLPrecision nextP = static_cast<GrSLPrecision>(precision + 1);
4117168df7798d0d12684f18df0556dc19e65b32e6bsalomon                info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP);
4217168df7798d0d12684f18df0556dc19e65b32e6bsalomon                if (!info->supported()) {
4317168df7798d0d12684f18df0556dc19e65b32e6bsalomon                    break;
4417168df7798d0d12684f18df0556dc19e65b32e6bsalomon                }
45bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                precision = nextP;
4617168df7798d0d12684f18df0556dc19e65b32e6bsalomon            } while (true);
4717168df7798d0d12684f18df0556dc19e65b32e6bsalomon        }
4817168df7798d0d12684f18df0556dc19e65b32e6bsalomon    }
49bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
50bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    return precision;
51bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips}
52bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
53bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillipsvoid GrCoordTransform::reset(const SkMatrix& m, const GrTexture* texture,
54bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                             GrSamplerParams::FilterMode filter, bool normalize) {
55bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    SkASSERT(texture);
56bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    SkASSERT(!fInProcessor);
57bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
58bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fMatrix = m;
59bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fTexture = texture;
60bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fNormalize = normalize;
61bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
62bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
63bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    if (texture->getContext()) {
64bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips        fPrecision = compute_precision(texture->getContext()->caps()->shaderCaps(),
65bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                                       texture->width(), texture->height(), filter);
66bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    } else {
67bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips        fPrecision = kDefault_GrSLPrecision;
68bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    }
69bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips}
70bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
71296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillipsvoid GrCoordTransform::reset(GrResourceProvider* resourceProvider, const SkMatrix& m,
72bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                             GrTextureProxy* proxy,
73bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                             GrSamplerParams::FilterMode filter, bool normalize) {
74bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    SkASSERT(proxy);
75bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    SkASSERT(!fInProcessor);
76bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
77bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fMatrix = m;
78bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    // MDB TODO: just GrCaps is needed for this method
79bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    // MDB TODO: once all the coord transforms take a proxy just store it here and
80bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    // instantiate later
81296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips    fTexture = proxy->instantiate(resourceProvider);
82bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fNormalize = normalize;
83bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
84bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips
85296b1ccf9b8e9c8b945645efcbaa9c71c7135f58Robert Phillips    const GrCaps* caps = resourceProvider->caps();
86bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips    fPrecision = compute_precision(caps->shaderCaps(),
87bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                                   proxy->worstCaseWidth(*caps),
88bc7a4fb06780f9829b4b21470fe6f0503d2297cdRobert Phillips                                   proxy->worstCaseHeight(*caps), filter);
8917168df7798d0d12684f18df0556dc19e65b32e6bsalomon}
9017168df7798d0d12684f18df0556dc19e65b32e6bsalomon
91