gfx/skia/trunk/src/gpu/GrDrawState.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2012 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  */
     8 #include "GrDrawState.h"
     9 #include "GrPaint.h"
    11 bool GrDrawState::setIdentityViewMatrix()  {
    12     if (fColorStages.count() || fCoverageStages.count()) {
    13         SkMatrix invVM;
    14         if (!fCommon.fViewMatrix.invert(&invVM)) {
    15             // sad trombone sound
    16             return false;
    17         }
    18         for (int s = 0; s < fColorStages.count(); ++s) {
    19             fColorStages[s].localCoordChange(invVM);
    20         }
    21         for (int s = 0; s < fCoverageStages.count(); ++s) {
    22             fCoverageStages[s].localCoordChange(invVM);
    23         }
    24     }
    25     fCommon.fViewMatrix.reset();
    26     return true;
    27 }
    29 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
    30     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
    32     fColorStages.reset();
    33     fCoverageStages.reset();
    35     for (int i = 0; i < paint.numColorStages(); ++i) {
    36         fColorStages.push_back(paint.getColorStage(i));
    37     }
    39     for (int i = 0; i < paint.numCoverageStages(); ++i) {
    40         fCoverageStages.push_back(paint.getCoverageStage(i));
    41     }
    43     this->setRenderTarget(rt);
    45     fCommon.fViewMatrix = vm;
    47     // These have no equivalent in GrPaint, set them to defaults
    48     fCommon.fBlendConstant = 0x0;
    49     fCommon.fDrawFace = kBoth_DrawFace;
    50     fCommon.fStencilSettings.setDisabled();
    51     this->resetStateFlags();
    53     // Enable the clip bit
    54     this->enableState(GrDrawState::kClip_StateBit);
    56     this->setColor(paint.getColor());
    57     this->setState(GrDrawState::kDither_StateBit, paint.isDither());
    58     this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
    60     this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
    61     this->setCoverage(paint.getCoverage());
    62 }
    64 ////////////////////////////////////////////////////////////////////////////////
    66 static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
    67     // this works as long as we're 4 byte-aligned
    68 #ifdef SK_DEBUG
    69     uint32_t overlapCheck = 0;
    70 #endif
    71     SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
    72     size_t size = 0;
    73     for (int index = 0; index < count; ++index) {
    74         size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
    75         size += attribSize;
    76 #ifdef SK_DEBUG
    77         size_t dwordCount = attribSize >> 2;
    78         uint32_t mask = (1 << dwordCount)-1;
    79         size_t offsetShift = attribs[index].fOffset >> 2;
    80         SkASSERT(!(overlapCheck & (mask << offsetShift)));
    81         overlapCheck |= (mask << offsetShift);
    82 #endif
    83     }
    84     return size;
    85 }
    87 size_t GrDrawState::getVertexSize() const {
    88     return vertex_size(fCommon.fVAPtr, fCommon.fVACount);
    89 }
    91 ////////////////////////////////////////////////////////////////////////////////
    93 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
    94     SkASSERT(count <= kMaxVertexAttribCnt);
    96     fCommon.fVAPtr = attribs;
    97     fCommon.fVACount = count;
    99     // Set all the indices to -1
   100     memset(fCommon.fFixedFunctionVertexAttribIndices,
   101            0xff,
   102            sizeof(fCommon.fFixedFunctionVertexAttribIndices));
   103 #ifdef SK_DEBUG
   104     uint32_t overlapCheck = 0;
   105 #endif
   106     for (int i = 0; i < count; ++i) {
   107         if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
   108             // The fixed function attribs can only be specified once
   109             SkASSERT(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
   110             SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
   111                      GrVertexAttribTypeVectorCount(attribs[i].fType));
   112             fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
   113         }
   114 #ifdef SK_DEBUG
   115         size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
   116         uint32_t mask = (1 << dwordCount)-1;
   117         size_t offsetShift = attribs[i].fOffset >> 2;
   118         SkASSERT(!(overlapCheck & (mask << offsetShift)));
   119         overlapCheck |= (mask << offsetShift);
   120 #endif
   121     }
   122     // Positions must be specified.
   123     SkASSERT(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
   124 }
   126 ////////////////////////////////////////////////////////////////////////////////
   128 void GrDrawState::setDefaultVertexAttribs() {
   129     static const GrVertexAttrib kPositionAttrib =
   130         {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
   132     fCommon.fVAPtr = &kPositionAttrib;
   133     fCommon.fVACount = 1;
   135     // set all the fixed function indices to -1 except position.
   136     memset(fCommon.fFixedFunctionVertexAttribIndices,
   137            0xff,
   138            sizeof(fCommon.fFixedFunctionVertexAttribIndices));
   139     fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
   140 }
   142 ////////////////////////////////////////////////////////////////////////////////
   144 bool GrDrawState::validateVertexAttribs() const {
   145     // check consistency of effects and attributes
   146     GrSLType slTypes[kMaxVertexAttribCnt];
   147     for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
   148         slTypes[i] = static_cast<GrSLType>(-1);
   149     }
   150     int totalStages = fColorStages.count() + fCoverageStages.count();
   151     for (int s = 0; s < totalStages; ++s) {
   152         int covIdx = s - fColorStages.count();
   153         const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx];
   154         const GrEffectRef* effect = stage.getEffect();
   155         SkASSERT(NULL != effect);
   156         // make sure that any attribute indices have the correct binding type, that the attrib
   157         // type and effect's shader lang type are compatible, and that attributes shared by
   158         // multiple effects use the same shader lang type.
   159         const int* attributeIndices = stage.getVertexAttribIndices();
   160         int numAttributes = stage.getVertexAttribIndexCount();
   161         for (int i = 0; i < numAttributes; ++i) {
   162             int attribIndex = attributeIndices[i];
   163             if (attribIndex >= fCommon.fVACount ||
   164                 kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) {
   165                 return false;
   166             }
   168             GrSLType effectSLType = (*effect)->vertexAttribType(i);
   169             GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType;
   170             int slVecCount = GrSLTypeVectorCount(effectSLType);
   171             int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
   172             if (slVecCount != attribVecCount ||
   173                 (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
   174                     slTypes[attribIndex] != effectSLType)) {
   175                 return false;
   176             }
   177             slTypes[attribIndex] = effectSLType;
   178         }
   179     }
   181     return true;
   182 }
   184 bool GrDrawState::willEffectReadDstColor() const {
   185     if (!this->isColorWriteDisabled()) {
   186         for (int s = 0; s < fColorStages.count(); ++s) {
   187             if ((*fColorStages[s].getEffect())->willReadDstColor()) {
   188                 return true;
   189             }
   190         }
   191     }
   192     for (int s = 0; s < fCoverageStages.count(); ++s) {
   193         if ((*fCoverageStages[s].getEffect())->willReadDstColor()) {
   194             return true;
   195         }
   196     }
   197     return false;
   198 }
   200 ////////////////////////////////////////////////////////////////////////////////
   202 bool GrDrawState::srcAlphaWillBeOne() const {
   203     uint32_t validComponentFlags;
   204     GrColor color;
   205     // Check if per-vertex or constant color may have partial alpha
   206     if (this->hasColorVertexAttribute()) {
   207         validComponentFlags = 0;
   208         color = 0; // not strictly necessary but we get false alarms from tools about uninit.
   209     } else {
   210         validComponentFlags = kRGBA_GrColorComponentFlags;
   211         color = this->getColor();
   212     }
   214     // Run through the color stages
   215     for (int s = 0; s < fColorStages.count(); ++s) {
   216         const GrEffectRef* effect = fColorStages[s].getEffect();
   217         (*effect)->getConstantColorComponents(&color, &validComponentFlags);
   218     }
   220     // Check whether coverage is treated as color. If so we run through the coverage computation.
   221     if (this->isCoverageDrawing()) {
   222         GrColor coverageColor = this->getCoverageColor();
   223         GrColor oldColor = color;
   224         color = 0;
   225         for (int c = 0; c < 4; ++c) {
   226             if (validComponentFlags & (1 << c)) {
   227                 U8CPU a = (oldColor >> (c * 8)) & 0xff;
   228                 U8CPU b = (coverageColor >> (c * 8)) & 0xff;
   229                 color |= (SkMulDiv255Round(a, b) << (c * 8));
   230             }
   231         }
   232         for (int s = 0; s < fCoverageStages.count(); ++s) {
   233             const GrEffectRef* effect = fCoverageStages[s].getEffect();
   234             (*effect)->getConstantColorComponents(&color, &validComponentFlags);
   235         }
   236     }
   237     return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
   238 }
   240 bool GrDrawState::hasSolidCoverage() const {
   241     // If we're drawing coverage directly then coverage is effectively treated as color.
   242     if (this->isCoverageDrawing()) {
   243         return true;
   244     }
   246     GrColor coverage;
   247     uint32_t validComponentFlags;
   248     // Initialize to an unknown starting coverage if per-vertex coverage is specified.
   249     if (this->hasCoverageVertexAttribute()) {
   250         validComponentFlags = 0;
   251     } else {
   252         coverage = fCommon.fCoverage;
   253         validComponentFlags = kRGBA_GrColorComponentFlags;
   254     }
   256     // Run through the coverage stages and see if the coverage will be all ones at the end.
   257     for (int s = 0; s < fCoverageStages.count(); ++s) {
   258         const GrEffectRef* effect = fCoverageStages[s].getEffect();
   259         (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
   260     }
   261     return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
   262 }
   264 ////////////////////////////////////////////////////////////////////////////////
   266 // Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
   267 // others will blend incorrectly.
   268 bool GrDrawState::canTweakAlphaForCoverage() const {
   269     /*
   270      The fractional coverage is f.
   271      The src and dst coeffs are Cs and Cd.
   272      The dst and src colors are S and D.
   273      We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
   274      we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
   275      term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
   276      find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
   277      Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
   278      color by definition.
   279      */
   280     return kOne_GrBlendCoeff == fCommon.fDstBlend ||
   281            kISA_GrBlendCoeff == fCommon.fDstBlend ||
   282            kISC_GrBlendCoeff == fCommon.fDstBlend ||
   283            this->isCoverageDrawing();
   284 }
   286 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
   287                                                      GrBlendCoeff* srcCoeff,
   288                                                      GrBlendCoeff* dstCoeff) const {
   290     GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
   291     if (NULL == srcCoeff) {
   292         srcCoeff = &bogusSrcCoeff;
   293     }
   294     *srcCoeff = this->getSrcBlendCoeff();
   296     if (NULL == dstCoeff) {
   297         dstCoeff = &bogusDstCoeff;
   298     }
   299     *dstCoeff = this->getDstBlendCoeff();
   301     if (this->isColorWriteDisabled()) {
   302         *srcCoeff = kZero_GrBlendCoeff;
   303         *dstCoeff = kOne_GrBlendCoeff;
   304     }
   306     bool srcAIsOne = this->srcAlphaWillBeOne();
   307     bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
   308                          (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
   309     bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
   310                          (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
   312     bool covIsZero = !this->isCoverageDrawing() &&
   313                      !this->hasCoverageVertexAttribute() &&
   314                      0 == this->getCoverageColor();
   315     // When coeffs are (0,1) there is no reason to draw at all, unless
   316     // stenciling is enabled. Having color writes disabled is effectively
   317     // (0,1). The same applies when coverage is known to be 0.
   318     if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
   319         if (this->getStencil().doesWrite()) {
   320             return kDisableBlend_BlendOptFlag |
   321                    kEmitCoverage_BlendOptFlag;
   322         } else {
   323             return kSkipDraw_BlendOptFlag;
   324         }
   325     }
   327     // check for coverage due to constant coverage, per-vertex coverage, or coverage stage
   328     bool hasCoverage = forceCoverage ||
   329                        0xffffffff != this->getCoverageColor() ||
   330                        this->hasCoverageVertexAttribute() ||
   331                        fCoverageStages.count() > 0;
   333     // if we don't have coverage we can check whether the dst
   334     // has to read at all. If not, we'll disable blending.
   335     if (!hasCoverage) {
   336         if (dstCoeffIsZero) {
   337             if (kOne_GrBlendCoeff == *srcCoeff) {
   338                 // if there is no coverage and coeffs are (1,0) then we
   339                 // won't need to read the dst at all, it gets replaced by src
   340                 return kDisableBlend_BlendOptFlag;
   341             } else if (kZero_GrBlendCoeff == *srcCoeff) {
   342                 // if the op is "clear" then we don't need to emit a color
   343                 // or blend, just write transparent black into the dst.
   344                 *srcCoeff = kOne_GrBlendCoeff;
   345                 *dstCoeff = kZero_GrBlendCoeff;
   346                 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
   347             }
   348         }
   349     } else if (this->isCoverageDrawing()) {
   350         // we have coverage but we aren't distinguishing it from alpha by request.
   351         return kCoverageAsAlpha_BlendOptFlag;
   352     } else {
   353         // check whether coverage can be safely rolled into alpha
   354         // of if we can skip color computation and just emit coverage
   355         if (this->canTweakAlphaForCoverage()) {
   356             return kCoverageAsAlpha_BlendOptFlag;
   357         }
   358         if (dstCoeffIsZero) {
   359             if (kZero_GrBlendCoeff == *srcCoeff) {
   360                 // the source color is not included in the blend
   361                 // the dst coeff is effectively zero so blend works out to:
   362                 // (c)(0)D + (1-c)D = (1-c)D.
   363                 *dstCoeff = kISA_GrBlendCoeff;
   364                 return  kEmitCoverage_BlendOptFlag;
   365             } else if (srcAIsOne) {
   366                 // the dst coeff is effectively zero so blend works out to:
   367                 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
   368                 // If Sa is 1 then we can replace Sa with c
   369                 // and set dst coeff to 1-Sa.
   370                 *dstCoeff = kISA_GrBlendCoeff;
   371                 return  kCoverageAsAlpha_BlendOptFlag;
   372             }
   373         } else if (dstCoeffIsOne) {
   374             // the dst coeff is effectively one so blend works out to:
   375             // cS + (c)(1)D + (1-c)D = cS + D.
   376             *dstCoeff = kOne_GrBlendCoeff;
   377             return  kCoverageAsAlpha_BlendOptFlag;
   378         }
   379     }
   380     if (kOne_GrBlendCoeff == *srcCoeff &&
   381         kZero_GrBlendCoeff == *dstCoeff &&
   382         this->willEffectReadDstColor()) {
   383         // In this case the shader will fully resolve the color, coverage, and dst and we don't
   384         // need blending.
   385         return kDisableBlend_BlendOptFlag;
   386     }
   387     return kNone_BlendOpt;
   388 }
   390 ////////////////////////////////////////////////////////////////////////////////
   392 void GrDrawState::AutoViewMatrixRestore::restore() {
   393     if (NULL != fDrawState) {
   394         SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
   395         fDrawState->fCommon.fViewMatrix = fViewMatrix;
   396         SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
   397         int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
   398         SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
   400         int i = 0;
   401         for (int s = 0; s < fNumColorStages; ++s, ++i) {
   402             fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
   403         }
   404         for (int s = 0; s < numCoverageStages; ++s, ++i) {
   405             fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
   406         }
   407         fDrawState = NULL;
   408     }
   409 }
   411 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
   412                                              const SkMatrix& preconcatMatrix) {
   413     this->restore();
   415     SkASSERT(NULL == fDrawState);
   416     if (NULL == drawState || preconcatMatrix.isIdentity()) {
   417         return;
   418     }
   419     fDrawState = drawState;
   421     fViewMatrix = drawState->getViewMatrix();
   422     drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix);
   424     this->doEffectCoordChanges(preconcatMatrix);
   425     SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   426 }
   428 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
   429     this->restore();
   431     if (NULL == drawState) {
   432         return false;
   433     }
   435     if (drawState->getViewMatrix().isIdentity()) {
   436         return true;
   437     }
   439     fViewMatrix = drawState->getViewMatrix();
   440     if (0 == drawState->numTotalStages()) {
   441         drawState->fCommon.fViewMatrix.reset();
   442         fDrawState = drawState;
   443         fNumColorStages = 0;
   444         fSavedCoordChanges.reset(0);
   445         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   446         return true;
   447     } else {
   448         SkMatrix inv;
   449         if (!fViewMatrix.invert(&inv)) {
   450             return false;
   451         }
   452         drawState->fCommon.fViewMatrix.reset();
   453         fDrawState = drawState;
   454         this->doEffectCoordChanges(inv);
   455         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   456         return true;
   457     }
   458 }
   460 void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
   461     fSavedCoordChanges.reset(fDrawState->numTotalStages());
   462     int i = 0;
   464     fNumColorStages = fDrawState->numColorStages();
   465     for (int s = 0; s < fNumColorStages; ++s, ++i) {
   466         fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]);
   467         fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
   468     }
   470     int numCoverageStages = fDrawState->numCoverageStages();
   471     for (int s = 0; s < numCoverageStages; ++s, ++i) {
   472         fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]);
   473         fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
   474     }
   475 }

mercurial