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