Home | History | Annotate | Download | only in gpu
      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 "GrCoordTransform.h"
      9 #include "GrCaps.h"
     10 #include "GrContext.h"
     11 #include "GrGpu.h"
     12 
     13 void GrCoordTransform::reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture,
     14                              GrTextureParams::FilterMode filter) {
     15     SkASSERT(texture);
     16     SkASSERT(!fInProcessor);
     17 
     18     fSourceCoords = sourceCoords;
     19     fMatrix = m;
     20     fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin();
     21 
     22     // Always start at kDefault. Then if precisions differ we see if the precision needs to be
     23     // increased. Our rule is that we want at least 4 subpixel values in the representation for
     24     // coords between 0 to 1 when bi- or tri-lerping and 1 value when nearest filtering. Note that
     25     // this still might not be enough when drawing with repeat or mirror-repeat modes but that case
     26     // can be arbitrarily bad.
     27     int subPixelThresh = filter > GrTextureParams::kNone_FilterMode ? 4 : 1;
     28     fPrecision = kDefault_GrSLPrecision;
     29     if (texture->getContext()) {
     30         const GrShaderCaps* caps = texture->getContext()->caps()->shaderCaps();
     31         if (caps->floatPrecisionVaries()) {
     32             int maxD = SkTMax(texture->width(), texture->height());
     33             const GrShaderCaps::PrecisionInfo* info;
     34             info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, fPrecision);
     35             do {
     36                 SkASSERT(info->supported());
     37                 // Make sure there is at least 2 bits of subpixel precision in the range of
     38                 // texture coords from 0.5 to 1.0.
     39                 if ((2 << info->fBits) / maxD > subPixelThresh) {
     40                     break;
     41                 }
     42                 if (kHigh_GrSLPrecision == fPrecision) {
     43                     break;
     44                 }
     45                 GrSLPrecision nextP = static_cast<GrSLPrecision>(fPrecision + 1);
     46                 info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP);
     47                 if (!info->supported()) {
     48                     break;
     49                 }
     50                 fPrecision = nextP;
     51             } while (true);
     52         }
     53     }
     54 }
     55 
     56 void GrCoordTransform::reset(GrCoordSet sourceCoords,
     57                              const SkMatrix& m,
     58                              GrSLPrecision precision) {
     59     SkASSERT(!fInProcessor);
     60     fSourceCoords = sourceCoords;
     61     fMatrix = m;
     62     fReverseY = false;
     63     fPrecision = precision;
     64 }
     65