Sat, 03 Jan 2015 20:18:00 +0100
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.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright 2012 Google Inc. |
michael@0 | 3 | * |
michael@0 | 4 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 5 | * found in the LICENSE file. |
michael@0 | 6 | */ |
michael@0 | 7 | |
michael@0 | 8 | #include "GrTextureDomain.h" |
michael@0 | 9 | #include "GrSimpleTextureEffect.h" |
michael@0 | 10 | #include "GrTBackendEffectFactory.h" |
michael@0 | 11 | #include "gl/GrGLEffect.h" |
michael@0 | 12 | #include "SkFloatingPoint.h" |
michael@0 | 13 | |
michael@0 | 14 | |
michael@0 | 15 | GrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index) |
michael@0 | 16 | : fIndex(index) { |
michael@0 | 17 | |
michael@0 | 18 | static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; |
michael@0 | 19 | if (domain.contains(kFullRect)) { |
michael@0 | 20 | fMode = kIgnore_Mode; |
michael@0 | 21 | } else { |
michael@0 | 22 | fMode = mode; |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | if (fMode != kIgnore_Mode) { |
michael@0 | 26 | // We don't currently handle domains that are empty or don't intersect the texture. |
michael@0 | 27 | // It is OK if the domain rect is a line or point, but it should not be inverted. We do not |
michael@0 | 28 | // handle rects that do not intersect the [0..1]x[0..1] rect. |
michael@0 | 29 | SkASSERT(domain.fLeft <= domain.fRight); |
michael@0 | 30 | SkASSERT(domain.fTop <= domain.fBottom); |
michael@0 | 31 | fDomain.fLeft = SkMaxScalar(domain.fLeft, kFullRect.fLeft); |
michael@0 | 32 | fDomain.fRight = SkMinScalar(domain.fRight, kFullRect.fRight); |
michael@0 | 33 | fDomain.fTop = SkMaxScalar(domain.fTop, kFullRect.fTop); |
michael@0 | 34 | fDomain.fBottom = SkMinScalar(domain.fBottom, kFullRect.fBottom); |
michael@0 | 35 | SkASSERT(fDomain.fLeft <= fDomain.fRight); |
michael@0 | 36 | SkASSERT(fDomain.fTop <= fDomain.fBottom); |
michael@0 | 37 | } |
michael@0 | 38 | } |
michael@0 | 39 | |
michael@0 | 40 | ////////////////////////////////////////////////////////////////////////////// |
michael@0 | 41 | |
michael@0 | 42 | void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder, |
michael@0 | 43 | const GrTextureDomain& textureDomain, |
michael@0 | 44 | const char* outColor, |
michael@0 | 45 | const SkString& inCoords, |
michael@0 | 46 | const GrGLEffect::TextureSampler sampler, |
michael@0 | 47 | const char* inModulateColor) { |
michael@0 | 48 | SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode); |
michael@0 | 49 | SkDEBUGCODE(fMode = textureDomain.mode();) |
michael@0 | 50 | |
michael@0 | 51 | if (kIgnore_Mode == textureDomain.mode()) { |
michael@0 | 52 | builder->fsCodeAppendf("\t%s = ", outColor); |
michael@0 | 53 | builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, |
michael@0 | 54 | inCoords.c_str()); |
michael@0 | 55 | builder->fsCodeAppend(";\n"); |
michael@0 | 56 | return; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | if (!fDomainUni.isValid()) { |
michael@0 | 60 | const char* name; |
michael@0 | 61 | SkString uniName("TexDom"); |
michael@0 | 62 | if (textureDomain.fIndex >= 0) { |
michael@0 | 63 | uniName.appendS32(textureDomain.fIndex); |
michael@0 | 64 | } |
michael@0 | 65 | fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
michael@0 | 66 | kVec4f_GrSLType, uniName.c_str(), &name); |
michael@0 | 67 | fDomainName = name; |
michael@0 | 68 | } |
michael@0 | 69 | if (kClamp_Mode == textureDomain.mode()) { |
michael@0 | 70 | SkString clampedCoords; |
michael@0 | 71 | clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)", |
michael@0 | 72 | inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str()); |
michael@0 | 73 | |
michael@0 | 74 | builder->fsCodeAppendf("\t%s = ", outColor); |
michael@0 | 75 | builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str()); |
michael@0 | 76 | builder->fsCodeAppend(";\n"); |
michael@0 | 77 | } else { |
michael@0 | 78 | SkASSERT(GrTextureDomain::kDecal_Mode == textureDomain.mode()); |
michael@0 | 79 | // Add a block since we're going to declare variables. |
michael@0 | 80 | GrGLShaderBuilder::FSBlock block(builder); |
michael@0 | 81 | |
michael@0 | 82 | const char* domain = fDomainName.c_str(); |
michael@0 | 83 | if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) { |
michael@0 | 84 | // On the NexusS and GalaxyNexus, the other path (with the 'any' |
michael@0 | 85 | // call) causes the compilation error "Calls to any function that |
michael@0 | 86 | // may require a gradient calculation inside a conditional block |
michael@0 | 87 | // may return undefined results". This appears to be an issue with |
michael@0 | 88 | // the 'any' call since even the simple "result=black; if (any()) |
michael@0 | 89 | // result=white;" code fails to compile. |
michael@0 | 90 | builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n"); |
michael@0 | 91 | builder->fsCodeAppend("\tvec4 inside = "); |
michael@0 | 92 | builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str()); |
michael@0 | 93 | builder->fsCodeAppend(";\n"); |
michael@0 | 94 | |
michael@0 | 95 | builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n", |
michael@0 | 96 | inCoords.c_str(), domain, domain, domain); |
michael@0 | 97 | builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n", |
michael@0 | 98 | inCoords.c_str(), domain, domain, domain); |
michael@0 | 99 | builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n"); |
michael@0 | 100 | builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor); |
michael@0 | 101 | } else { |
michael@0 | 102 | builder->fsCodeAppend("\tbvec4 outside;\n"); |
michael@0 | 103 | builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(), |
michael@0 | 104 | domain); |
michael@0 | 105 | builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(), |
michael@0 | 106 | domain); |
michael@0 | 107 | builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outColor); |
michael@0 | 108 | builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str()); |
michael@0 | 109 | builder->fsCodeAppend(";\n"); |
michael@0 | 110 | } |
michael@0 | 111 | } |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | void GrTextureDomain::GLDomain::setData(const GrGLUniformManager& uman, |
michael@0 | 115 | const GrTextureDomain& textureDomain, |
michael@0 | 116 | GrSurfaceOrigin textureOrigin) { |
michael@0 | 117 | SkASSERT(textureDomain.mode() == fMode); |
michael@0 | 118 | if (kIgnore_Mode != textureDomain.mode()) { |
michael@0 | 119 | GrGLfloat values[4] = { |
michael@0 | 120 | SkScalarToFloat(textureDomain.domain().left()), |
michael@0 | 121 | SkScalarToFloat(textureDomain.domain().top()), |
michael@0 | 122 | SkScalarToFloat(textureDomain.domain().right()), |
michael@0 | 123 | SkScalarToFloat(textureDomain.domain().bottom()) |
michael@0 | 124 | }; |
michael@0 | 125 | // vertical flip if necessary |
michael@0 | 126 | if (kBottomLeft_GrSurfaceOrigin == textureOrigin) { |
michael@0 | 127 | values[1] = 1.0f - values[1]; |
michael@0 | 128 | values[3] = 1.0f - values[3]; |
michael@0 | 129 | // The top and bottom were just flipped, so correct the ordering |
michael@0 | 130 | // of elements so that values = (l, t, r, b). |
michael@0 | 131 | SkTSwap(values[1], values[3]); |
michael@0 | 132 | } |
michael@0 | 133 | if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) { |
michael@0 | 134 | uman.set4fv(fDomainUni, 1, values); |
michael@0 | 135 | memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat)); |
michael@0 | 136 | } |
michael@0 | 137 | } |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | |
michael@0 | 141 | ////////////////////////////////////////////////////////////////////////////// |
michael@0 | 142 | |
michael@0 | 143 | class GrGLTextureDomainEffect : public GrGLEffect { |
michael@0 | 144 | public: |
michael@0 | 145 | GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
michael@0 | 146 | |
michael@0 | 147 | virtual void emitCode(GrGLShaderBuilder*, |
michael@0 | 148 | const GrDrawEffect&, |
michael@0 | 149 | EffectKey, |
michael@0 | 150 | const char* outputColor, |
michael@0 | 151 | const char* inputColor, |
michael@0 | 152 | const TransformedCoordsArray&, |
michael@0 | 153 | const TextureSamplerArray&) SK_OVERRIDE; |
michael@0 | 154 | |
michael@0 | 155 | virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; |
michael@0 | 156 | |
michael@0 | 157 | static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); |
michael@0 | 158 | |
michael@0 | 159 | private: |
michael@0 | 160 | GrTextureDomain::GLDomain fGLDomain; |
michael@0 | 161 | typedef GrGLEffect INHERITED; |
michael@0 | 162 | }; |
michael@0 | 163 | |
michael@0 | 164 | GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory, |
michael@0 | 165 | const GrDrawEffect&) |
michael@0 | 166 | : INHERITED(factory) { |
michael@0 | 167 | } |
michael@0 | 168 | |
michael@0 | 169 | void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder, |
michael@0 | 170 | const GrDrawEffect& drawEffect, |
michael@0 | 171 | EffectKey key, |
michael@0 | 172 | const char* outputColor, |
michael@0 | 173 | const char* inputColor, |
michael@0 | 174 | const TransformedCoordsArray& coords, |
michael@0 | 175 | const TextureSamplerArray& samplers) { |
michael@0 | 176 | const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>(); |
michael@0 | 177 | const GrTextureDomain& domain = effect.textureDomain(); |
michael@0 | 178 | |
michael@0 | 179 | SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
michael@0 | 180 | fGLDomain.sampleTexture(builder, domain, outputColor, coords2D, samplers[0], inputColor); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, |
michael@0 | 184 | const GrDrawEffect& drawEffect) { |
michael@0 | 185 | const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>(); |
michael@0 | 186 | const GrTextureDomain& domain = effect.textureDomain(); |
michael@0 | 187 | fGLDomain.setData(uman, domain, effect.texture(0)->origin()); |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect, |
michael@0 | 191 | const GrGLCaps&) { |
michael@0 | 192 | const GrTextureDomain& domain = drawEffect.castEffect<GrTextureDomainEffect>().textureDomain(); |
michael@0 | 193 | return GrTextureDomain::GLDomain::DomainKey(domain); |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | |
michael@0 | 197 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 198 | |
michael@0 | 199 | GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture, |
michael@0 | 200 | const SkMatrix& matrix, |
michael@0 | 201 | const SkRect& domain, |
michael@0 | 202 | GrTextureDomain::Mode mode, |
michael@0 | 203 | GrTextureParams::FilterMode filterMode, |
michael@0 | 204 | GrCoordSet coordSet) { |
michael@0 | 205 | static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; |
michael@0 | 206 | if (GrTextureDomain::kIgnore_Mode == mode || |
michael@0 | 207 | (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) { |
michael@0 | 208 | return GrSimpleTextureEffect::Create(texture, matrix, filterMode); |
michael@0 | 209 | } else { |
michael@0 | 210 | |
michael@0 | 211 | AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture, |
michael@0 | 212 | matrix, |
michael@0 | 213 | domain, |
michael@0 | 214 | mode, |
michael@0 | 215 | filterMode, |
michael@0 | 216 | coordSet))); |
michael@0 | 217 | return CreateEffectRef(effect); |
michael@0 | 218 | |
michael@0 | 219 | } |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, |
michael@0 | 223 | const SkMatrix& matrix, |
michael@0 | 224 | const SkRect& domain, |
michael@0 | 225 | GrTextureDomain::Mode mode, |
michael@0 | 226 | GrTextureParams::FilterMode filterMode, |
michael@0 | 227 | GrCoordSet coordSet) |
michael@0 | 228 | : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) |
michael@0 | 229 | , fTextureDomain(domain, mode) { |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | GrTextureDomainEffect::~GrTextureDomainEffect() { |
michael@0 | 233 | |
michael@0 | 234 | } |
michael@0 | 235 | |
michael@0 | 236 | const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const { |
michael@0 | 237 | return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance(); |
michael@0 | 238 | } |
michael@0 | 239 | |
michael@0 | 240 | bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const { |
michael@0 | 241 | const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase); |
michael@0 | 242 | return this->hasSameTextureParamsMatrixAndSourceCoords(s) && |
michael@0 | 243 | this->fTextureDomain == s.fTextureDomain; |
michael@0 | 244 | } |
michael@0 | 245 | |
michael@0 | 246 | void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { |
michael@0 | 247 | if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper |
michael@0 | 248 | *validFlags = 0; |
michael@0 | 249 | } else { |
michael@0 | 250 | this->updateConstantColorComponentsForModulation(color, validFlags); |
michael@0 | 251 | } |
michael@0 | 252 | } |
michael@0 | 253 | |
michael@0 | 254 | /////////////////////////////////////////////////////////////////////////////// |
michael@0 | 255 | |
michael@0 | 256 | GR_DEFINE_EFFECT_TEST(GrTextureDomainEffect); |
michael@0 | 257 | |
michael@0 | 258 | GrEffectRef* GrTextureDomainEffect::TestCreate(SkRandom* random, |
michael@0 | 259 | GrContext*, |
michael@0 | 260 | const GrDrawTargetCaps&, |
michael@0 | 261 | GrTexture* textures[]) { |
michael@0 | 262 | int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : |
michael@0 | 263 | GrEffectUnitTest::kAlphaTextureIdx; |
michael@0 | 264 | SkRect domain; |
michael@0 | 265 | domain.fLeft = random->nextUScalar1(); |
michael@0 | 266 | domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1); |
michael@0 | 267 | domain.fTop = random->nextUScalar1(); |
michael@0 | 268 | domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1); |
michael@0 | 269 | GrTextureDomain::Mode mode = |
michael@0 | 270 | (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCount); |
michael@0 | 271 | const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); |
michael@0 | 272 | bool bilerp = random->nextBool(); |
michael@0 | 273 | GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet; |
michael@0 | 274 | return GrTextureDomainEffect::Create(textures[texIdx], |
michael@0 | 275 | matrix, |
michael@0 | 276 | domain, |
michael@0 | 277 | mode, |
michael@0 | 278 | bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode, |
michael@0 | 279 | coords); |
michael@0 | 280 | } |